Iceberg REST Catalog: De Nieuwe Standaard voor Data Mesh

Gepubliceerd: 9 april 2026
Leestijd: 12 minuten
Data Engineering

Ontdek hoe de Iceberg REST Catalog protocol data mesh architecturen transformeert en interoperabiliteit tussen platformen mogelijk maakt.

```html

Wat is de Iceberg REST Catalog — en waarom is het in 2026 onmisbaar?

De datawereld beweegt razendsnel. Waar organisaties een paar jaar geleden nog genoegen namen met één centrale data warehouse, zien we nu een breed landschap van engines, clouds en teams die elk hun eigen stukje data beheren. Data Mesh is daarbij geen hype meer: het is een architectuurparadigma dat in 2026 bij veel Nederlandse enterprise-organisaties in productie draait. Maar data mesh brengt een hardnekkig probleem mee — hoe zorg je dat al die gedecentraliseerde dataproducten elkaar kunnen vinden en vertrouwen?

Hier komt de Iceberg REST Catalog om de hoek kijken. Apache Iceberg is al jaren de de-facto standaard voor open table formats in het data lakehouse. De REST Catalog specificatie — officieel onderdeel van de Apache Iceberg community — definieert een vendor-neutrale HTTP API waarmee elke engine (Spark, Trino, Flink, DuckDB, Snowflake, ...) tabellen kan registreren, opzoeken en beheren zonder vendor lock-in.

Definitie: Iceberg REST Catalog

De Iceberg REST Catalog is een open API-specificatie (OpenAPI 3.0) die beschrijft hoe clients via standaard HTTP-endpoints namespaces, tabellen en views in een Iceberg-catalogus kunnen beheren. Elke server die deze spec implementeert is compatibel met elke Iceberg-client — ongeacht cloud, taal of engine.

In 2026 zijn er meerdere volwassen implementaties beschikbaar: Apache Polaris (open source, gedoneerd door Snowflake), Unity Catalog (Databricks, recent open-source gegaan), Gravitino (Apache incubator), en cloud-native opties als AWS Glue REST endpoint en Azure Purview REST bridge. De strijd om de "open catalog standaard" is actueler dan ooit — en Nederlandse data engineers staan voor concrete keuzes.

Waarom dit nu relevant is voor Nederland

  • De Europese Data Act en GDPR verplichten organisaties tot aantoonbare data lineage en governance — een REST Catalog maakt dit engine-onafhankelijk mogelijk.
  • Steeds meer Nederlandse scale-ups en financiële instellingen bouwen multi-cloud platforms waarbij Snowflake, Databricks én open-source tools naast elkaar draaien.
  • De data mesh adoptie in sectoren als retail, overheid en logistiek creëert behoefte aan een neutrale "data contract registry" — precies wat de REST Catalog biedt.

Hoe werkt de Iceberg REST Catalog?

Laten we de architectuur stap voor stap doorlopen. De REST Catalog volgt een client-server model waarbij de catalogusserver de bron van waarheid is voor tabel-metadata, en engines enkel nog via HTTP praten in plaats van rechtstreeks naar een metastore.

1

Authenticatie & Namespace Discovery

De client authenticeert via OAuth 2.0 (client credentials flow) en haalt vervolgens de beschikbare namespaces op via GET /v1/namespaces. Een namespace is equivalent aan een database of schema in traditionele systemen.

2

Tabel Registratie

Een nieuwe tabel wordt geregistreerd via POST /v1/namespaces/{namespace}/tables met een volledig Iceberg schema, partitie-spec en sort-order in de request body. De server retourneert een table metadata location — een pointer naar de JSON metadata file op object storage.

3

Optimistic Locking via Commits

Writes gaan via POST /v1/namespaces/{namespace}/tables/{table}/commits. De client stuurt de current snapshot ID mee; de server weigert de commit als een andere schrijver ondertussen een nieuwe snapshot heeft gepubliceerd. Dit garandeert ACID-semantiek zonder distributed locks.

4

Credential Vending

Een krachtige feature: de catalogusserver kan via POST /v1/namespaces/{namespace}/tables/{table}/credentials tijdelijke, scope-beperkte cloud credentials uitdelen (bijv. STS tokens voor S3). De engine hoeft zelf geen permanente cloud-credentials te bevatten.

5

Views & Multi-Table Operaties

Iceberg Views (RFC geaccepteerd in 2024) worden beheerd via /v1/namespaces/{namespace}/views. Multi-table commits — nodig voor atomische operaties over meerdere tabellen — zijn beschikbaar via de transactions extensie in de spec v0.2+.

Architectuur in één oogopslag

Laag Component Protocol Verantwoordelijkheid
Query Engine Spark / Trino / Flink / DuckDB Iceberg REST Client Leest/schrijft data files; beheert snapshots
Catalog API Polaris / Unity / Gravitino HTTPS + OAuth 2.0 Metadata beheer, access control, credential vending
Metadata Storage PostgreSQL / DynamoDB / GCS JDBC / SDK Opslaan catalog state en metadata pointers
Data Storage S3 / ADLS / GCS S3 API Bewaren van Parquet/ORC/Avro data files

Praktische Codevoorbeelden

3.1 Apache Spark verbinden met een REST Catalog (Polaris)

Onderstaand voorbeeld configureert PySpark om via de REST Catalog te praten met een lokale Polaris-instantie. Dit werkt identiek tegen Unity Catalog of elke andere compliant server — enkel de uri en credentials veranderen.

from pyspark.sql import SparkSession

spark = (
    SparkSession.builder
    .appName("iceberg-rest-demo")
    # Iceberg Spark runtime (pas versie aan op je cluster)
    .config("spark.jars.packages",
            "org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:1.6.1,"
            "org.apache.iceberg:iceberg-aws-bundle:1.6.1")
    # Catalogus configuratie
    .config("spark.sql.catalog.prod", "org.apache.iceberg.spark.SparkCatalog")
    .config("spark.sql.catalog.prod.type", "rest")
    .config("spark.sql.catalog.prod.uri", "https://catalog.mijnbedrijf.nl/iceberg")
    .config("spark.sql.catalog.prod.credential",
            "client_id:super_geheim_secret")
    .config("spark.sql.catalog.prod.scope", "PRINCIPAL_ROLE:data_engineer")
    # Warehouse locatie op S3
    .config("spark.sql.catalog.prod.warehouse", "s3://mijn-lakehouse/warehouse")
    .config("spark.sql.catalog.prod.s3.region", "eu-west-1")
    # Credential vending inschakelen (Polaris feature)
    .config("spark.sql.catalog.prod.header.X-Iceberg-Access-Delegation",
            "vended-credentials")
    .getOrCreate()
)

# Namespace aanmaken
spark.sql("CREATE NAMESPACE IF NOT EXISTS prod.verkoop")

# Tabel aanmaken met partitionering
spark.sql("""
    CREATE TABLE IF NOT EXISTS prod.verkoop.orders (
        order_id     BIGINT,
        klant_id     BIGINT,
        bedrag       DECIMAL(10, 2),
        valuta       STRING,
        bestel_datum DATE,
        status       STRING
    )
    USING iceberg
    PARTITIONED BY (months(bestel_datum), status)
    TBLPROPERTIES (
        'write.format.default'          = 'parquet',
        'write.parquet.compression-codec' = 'zstd',
        'write.metadata.metrics.default'  = 'full'
    )
""")

print("Tabel succesvol aangemaakt via REST Catalog!")

3.2 Directe REST API aanroepen met Python (requests)

Soms wil je buiten Spark om de catalog bevragen — voor monitoring, governance tooling of een custom data mesh control plane. Onderstaand script laat zien hoe dat werkt met de standaard REST API.

import requests
from datetime import datetime, timedelta

CATALOG_URL  = "https://catalog.mijnbedrijf.nl/iceberg"
TOKEN_URL    = "https://catalog.mijnbedrijf.nl/oauth/tokens"
CLIENT_ID    = "data-platform-service"
CLIENT_SECRET = "super_geheim_secret"

# Stap 1: OAuth 2.0 token ophalen
def get_access_token() -> str:
    resp = requests.post(TOKEN_URL, data={
        "grant_type"   : "client_credentials",
        "client_id"    : CLIENT_ID,
        "client_secret": CLIENT_SECRET,
        "scope"        : "PRINCIPAL_ROLE:data_engineer",
    })
    resp.raise_for_status()
    return resp.json()["access_token"]

token = get_access_token()
headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type" : "application/json",
}

# Stap 2: Alle namespaces ophalen
namespaces = requests.get(
    f"{CATALOG_URL}/v1/namespaces",
    headers=headers,
).json()
print("Beschikbare namespaces:", namespaces["namespaces"])

# Stap 3: Tabellen in een namespace ophalen
tabellen = requests.get(
    f"{CATALOG_URL}/v1/namespaces/verkoop/tables",
    headers=headers,
).json()
print("Tabellen in 'verkoop':", [t["name"] for t in tabellen["identifiers"]])

# Stap 4: Tabel metadata ophalen
meta = requests.get(
    f"{CATALOG_URL}/v1/namespaces/verkoop/tables/orders",
    headers=headers,
).json()

schema    = meta["metadata"]["current-schema-id"]
snapshots = len(meta["metadata"].get("snapshots", []))
locatie   = meta["metadata-location"]

print(f"Schema ID  : {schema}")
print(f"Snapshots  : {snapshots}")
print(f"Metadata   : {locatie}")

3.3 DuckDB als lichtgewicht query engine op dezelfde catalogus

Een van de grootste voordelen van de REST Catalog is dat elke compatibele engine direct toegang heeft. Hier laten we zien hoe een data analist met DuckDB de prod.verkoop.orders tabel kan bevragen zonder Spark of speciale infrastractuur.

-- DuckDB (v1.1+) ondersteunt de Iceberg REST Catalog natively
-- via de iceberg extensie

INSTALL iceberg;
LOAD iceberg;

-- REST Catalog configureren
CREATE SECRET catalog_secret (
    TYPE        ICEBERG,
    ENDPOINT    'https://catalog.mijnbedrijf.nl/iceberg',
    CLIENT_ID   'duckdb-analyst',
    SECRET      'analyst_secret',
    TOKEN_ENDPOINT 'https://catalog.mijnbedrijf.nl/oauth/tokens'
);

-- Attach de catalogus
ATTACH '' AS prod (
    TYPE    ICEBERG,
    SECRET  catalog_secret,
    CATALOG 'prod'
);

-- Gewoon SQL draaien op Iceberg tabellen
SELECT
    date_trunc('month', bestel_datum) AS maand,
    valuta,
    COUNT(*)                          AS aantal_orders,
    SUM(bedrag)                       AS totaal_bedrag
FROM prod.verkoop.orders
WHERE status = 'VOLTOOID'
  AND bestel_datum >= CURRENT_DATE - INTERVAL 6 MONTH
GROUP BY 1, 2
ORDER BY 1 DESC, 4 DESC;

Pro tip: Credential Vending beveiligt je data lake

Door credential vending in te schakelen, geef je engines nooit permanente S3/ADLS-credentials. De catalog server geeft per-sessie STS tokens uit met exacte path-scope. Combineer dit met een korte TTL (bijv. 15 minuten) en je hebt een zero-trust data lake zonder aanpassingen in je engines.

Vergelijking: REST Catalog implementaties in 2026

De keuze van de catalogus-server is strategisch. Hieronder een eerlijke vergelijking van de drie meest gebruikte opties in de Nederlandse markt.

Criterium Apache Polaris Unity Catalog Gravitino
Licentie Apache 2.0 (open source) Apache 2.0 (open source, 2024) Apache 2.0 (incubating)
REST Catalog compliant ✅ Volledig ✅ Volledig ⚠️ Gedeeltelijk (v0.1)
Credential Vending ✅ Ja (STS, ADLS, GCS) ⚠️ Via Databricks runtime ❌ Nog niet
Multi-cloud ✅ AWS, Azure, GCP ⚠️ Primair AWS + Azure ✅ Cloud-agnostisch
Fine-grained Access Control ✅ Column + row level ✅ Column + row level ⚠️ Tabel-niveau
Data Lineage Beperkt (via extensies) ✅ Ingebouwd ✅ OpenLineage support
Productie-rijpheid (NL) ⭐⭐⭐⭐ Stabiel ⭐⭐⭐⭐⭐ Breed gebruikt ⭐⭐⭐ Opkomend
Ideaal voor Multi-engine, vendor-neutraal Databricks-centrisch Heterogene catalogi

Apache Polaris

Ideale keuze als je een echt vendor-neutrale catalogus wilt. Snowflake gebruikt het intern maar heeft de code volledig open-source gezet. Draait prima op Kubernetes en werkt out-of-the-box met Spark, Trino en Flink.

Unity Catalog

De sterkste keuze voor teams die al zwaar investeren in Databricks. De open-source release maakt het ook bruikbaar buiten Databricks, maar de governance-tooling schittert pas echt binnen het Databricks-ecosysteem.

Apache Gravitino

Het meest ambitieuze project: een unified metadata layer die niet alleen Iceberg maar ook Hive, Delta en zelfs relational databases catalogiseert. Interessant voor organisaties met een zeer heterogeen datalandschap.

Best Practices & Production Tips

Praktijkvoorbeeld: Nederlandse retailer met data mesh

Een Nederlandse retailer met 8 domeinteams (inkoop, logistiek, marketing, etc.) implementeerde Apache Polaris als centrale REST Catalog. Elk domein beheert zijn eigen namespace (inkoop.*, logistiek.*) maar alle engines — Spark voor batch, Flink voor streaming, Trino voor ad-hoc en dbt voor transformaties — praten via dezelfde REST API. Resultaat: geen Hive Metastore meer, 40% minder metadata-gerelateerde incidenten en volledige GDPR-aantoonbaarheid via catalog audit logs.

Tip 1: Namespace Strategie voor Data Mesh

In een data mesh architectuur is de namespace-hiërarchie de basis van je governance model. Gebruik een drielagen aanpak:

-- Aanbevolen namespace structuur
-- Laag 1: Domein
-- Laag 2: Zone (bronze/silver/gold of raw/curated/serving)
-- Laag 3: Dataset naam

-- Voorbeeld namespaces
inkoop.bronze.leverancier_orders
inkoop.silver.leverancier_orders_cleaned
inkoop.gold.leverancier_kpi_dashboard

logistiek.bronze.zendingen_raw
logistiek.silver.zendingen_verrijkt
logistiek.gold.levertijd_analyse

-- PRINCIPAL_ROLE per domein + zone
-- inkoop_bronze_reader  → alleen lezen op inkoop.bronze.*
-- inkoop_silver_writer  → schrijven op inkoop.silver.*
-- data_platform_admin   → alles

Tip 2: Automatiseer table properties voor compliance

-- Standaard tabel-template voor AVG-compliance
-- Gebruik een dbt macro of Terraform provider om dit consistent toe te passen

CREATE TABLE prod.marketing.klant_segmenten (
    klant_id      BIGINT        COMMENT 'Gepseudonimiseerd klant ID',
    segment       STRING        COMMENT 'Marketing segment label',
    score         DOUBLE        COMMENT 'Propensity score 0-1',
    berekend_op   TIMESTAMP     COMMENT 'Berekeningsmoment'
)
USING iceberg
TBLPROPERTIES (
    -- Data governance
    'comment'                    = 'Klant segmentatie voor marketing campagnes',
    'data_owner'                 = 'marketing-domein@mijnbedrijf.nl',
    'data_classification'        = 'CONFIDENTIAL',
    'gdpr_basis'                 = 'gerechtvaardigd_belang',
    'gdpr_retention_days'        = '365',
    -- Write optimalisaties
    'write.target-file-size-bytes' = '134217728',  -- 128 MB
    'write.parquet.compression-codec' = 'zstd',
    -- Maintenance
    'write.metadata.delete-after-commit.enabled' = 'true',
    'write.metadata.previous-versions-max'       = '5'
);

Tip 3: Health monitoring van je catalogus

import requests
import time
from prometheus_client import Gauge, start_http_server

# Prometheus metrics voor catalog monitoring
catalog_tables_total = Gauge(
    'iceberg_catalog_tables_total',
    'Totaal aantal tabellen per namespace',
    ['namespace']
)
catalog_response_ms = Gauge(
    'iceberg_catalog_response_ms',
    'REST Catalog response tijd in milliseconden'
)

def poll_catalog_health(catalog_url: str, headers: dict):
    """Poll de REST Catalog en exporteer metrics naar Prometheus."""
    start = time.time()

    namespaces_resp = requests.get(
        f"{catalog_url}/v1/namespaces",
        headers=headers,
        timeout=10,
    )
    elapsed_ms = (time.time() - start) * 1000
    catalog_response_ms.set(elapsed_ms)

    for ns in namespaces_resp.json().get("namespaces", []):
        ns_name = ".".join(ns)
        tables_resp = requests.get(
            f"{catalog_url}/v1/namespaces/{ns_name}/tables",
            headers=headers,
            timeout=10,
        )
        count = len(tables_resp.json().get("identifiers", []))
        catalog_tables_total.labels(namespace=ns_name).set(count)

if __name__ == "__main__":
    start_http_server(8000)  # Prometheus scrape endpoint
    token   = get_access_token()          # zie eerdere snippet
    headers = {"Authorization": f"Bearer {token}"}

    while True:
        poll_catalog_health("https://catalog.mijnbedrijf.nl/iceberg", headers)
        time.sleep(60)

Production Checklist

  • TLS overal: Nooit plain HTTP in productie — ook niet intern tussen engines en catalog.
  • Token TTL kort houden: Access tokens maximaal 1 uur, credential vending tokens 15 minuten.
  • Catalog HA: Zet de catalogus server achter een load balancer met minimaal 2 replicas en een externe PostgreSQL (geen embedded database).
  • Metadata compaction: Stel write.metadata.previous-versions-max in op 10 en draai wekelijks CALL system.expire_snapshots().
  • Audit logging: Activeer catalog audit logs en stuur deze naar je SIEM — elke tabel-toegang is dan aantoonbaar voor AVG/SOC2.
  • dbt Catalog Integration: Gebruik dbt-iceberg met de REST adapter zodat dbt docs automatisch tabel-metadata uit de catalog leest.

Conclusie: Wanneer wel (en niet) overstappen?

De Iceberg REST Catalog is geen silver bullet, maar in 2026 is het de dichtstbijzijnde standaard die de datawereld heeft voor interoperabele, engine-onafhankelijke metadata. De spec is stabiel, de implementaties zijn productie-rijp en de adoptie door zowel cloud vendors als open-source communities geeft vertrouwen dat dit geen tijdelijke trend is.

Gebruik het WEL als...

  • Je meer dan één query engine gebruikt
  • Je een data mesh architectuur implementeert
  • Je vendor lock-in wilt vermijden
  • Je strikte compliance-vereisten hebt (AVG, SOC2)
  • Je multi-cloud of hybrid cloud draait

Wacht ermee als...

  • Je 100% all-in Databricks bent (Unity Catalog is dan geïntegreerder)
  • Je team nog geen Iceberg ervaring heeft
  • Je < 100 tabellen beheert in één engine
  • Je bestaande Hive Metastore perfect werkt

Stappenplan voor starters

  • Start met Polaris lokaal via Docker
  • Migreer één niet-kritieke namespace
  • Test met Spark + DuckDB parallel