Apache Iceberg is a big data system which is effectively a set of columnar data files and a metadata catalog of what data's in those files. You can get one off the shelf from many vendors and providers, but for local dev that can be annoying.
So this is a simple local mock/proxy for multitenanted Iceberg. This means the user gets a token, and sees an Iceberg limited only to the tenant they're using (eg, MyCompany). However under the covers, we can use flat file storage or service role IAM to S3 etc without having to link the user identity to the upstream provider directly.
This is a service layer using bearer tokens, it is not a browser based webapp.
| Method | Path | Status |
|---|---|---|
| GET | /v1/config |
✓ Implemented |
| Method | Path | Status |
|---|---|---|
| GET | /v1/namespaces |
✓ Implemented |
| POST | /v1/namespaces |
✓ Implemented |
| GET | /v1/namespaces/{ns} |
✓ Implemented |
| HEAD | /v1/namespaces/{ns} |
✓ Implemented |
| POST | /v1/namespaces/{ns}/properties |
✓ Implemented |
| DELETE | /v1/namespaces/{ns} |
✓ Implemented |
| POST | /v1/namespaces/{ns}/register |
✓ Implemented |
| Method | Path | Status |
|---|---|---|
| GET | /v1/namespaces/{ns}/tables |
✓ Implemented |
| POST | /v1/namespaces/{ns}/tables |
✓ Implemented |
| GET | /v1/namespaces/{ns}/tables/{table} |
✓ Implemented |
| POST | /v1/namespaces/{ns}/tables/{table} |
✓ Implemented (commit updates) |
| HEAD | /v1/namespaces/{ns}/tables/{table} |
✓ Implemented |
| DELETE | /v1/namespaces/{ns}/tables/{table} |
✓ Implemented |
| POST | /v1/tables/rename |
✓ Implemented |
| Method | Path | Status |
|---|---|---|
| GET | /v1/data/{path} |
✓ Implemented (streaming blob read) |
| PUT | /v1/data/{path} |
✓ Implemented (streaming blob write) |
Note: Advanced features like views, transactions, scan planning, metrics, and vended credentials are not implemented. This implementation provides a complete core REST catalog suitable for local development and testing.
dotnet run --project src/Meeze.ThinIce.AppThe app starts on http://localhost:5000 by default.
dotnet test ThinIce.slndotnet publish src/Meeze.ThinIce.App -c ReleaseThe development config (appsettings.Development.json) ships with two tokens:
freeze-ray-token-001→ tenantSnowyConesIceCream, usermrfreeze@example.comice-age-token-002→ tenantWayneEnterprises, userbatman@example.org
Get catalog config:
curl http://localhost:5000/v1/configCreate a namespace:
curl -X POST http://localhost:5000/v1/namespaces \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"namespace": ["analytics"], "properties": {"owner": "data-team"}}'List namespaces:
curl http://localhost:5000/v1/namespaces \
-H "Authorization: Bearer <access_token>"Create a table:
curl -X POST http://localhost:5000/v1/namespaces/analytics/tables \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{"name": "events", "schema": {"type": "struct", "fields": [{"id": 1, "name": "ts", "type": "timestamp", "required": true}]}}'Write data (blob):
curl -X PUT http://localhost:5000/v1/data/warehouse/events/data.parquet \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/octet-stream" \
--data-binary @data.parquetRead data (blob):
curl http://localhost:5000/v1/data/warehouse/events/data.parquet \
-H "Authorization: Bearer <access_token>" \
-o data.parquet