<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://developer.overheid.nl/blog</id>
    <title>developer.overheid.nl Blog</title>
    <updated>2026-09-10T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://developer.overheid.nl/blog"/>
    <subtitle>developer.overheid.nl Blog</subtitle>
    <icon>https://developer.overheid.nl/favicon.svg</icon>
    <entry>
        <title type="html"><![CDATA[De BAG-API: van technische ontsluiting naar productgericht ontwikkelen]]></title>
        <id>https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen</id>
        <link href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen"/>
        <updated>2026-09-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[De BAG-API van het Kadaster begon als bijproduct van een dataplatform en
groeide uit tot een van de meest gebruikte API's van de overheid.
Productmanager Janette Storm vertelt hoe de focus verschoof van technische
ontsluiting naar productgericht ontwikkelen, en wat andere
overheidsorganisaties daarvan kunnen leren.
]]></summary>
        <content type="html"><![CDATA[<p>Van een aanvraag voor een bouwvergunning tot de kaarten in je navigatiesysteem.
De Basisregistratie Adressen en Gebouwen (BAG) is een enorme publieke
gegevensbron die dagelijks meer dan tien miljoen keer wordt geraadpleegd. Dit
gebeurt onder andere via de BAG-API van het Kadaster, inmiddels een van de meest
gebruikte API's in het overheidsdomein.</p>
<p>De beschikbaarheid van publieke adres- en gebouwgegevens heeft door de jaren
heen een flinke evolutie doorlopen. Vóór de BAG had elke gemeente meerdere
adresregistraties en dat maakte gegevensuitwisseling lastig. Met de BAG kwam
daar verandering in: één centrale registratie, beheerd door het Kadaster en
onderhouden door gemeenten. Dit maakte de uitwisseling van deze gegevens al een
stuk eenvoudiger. Ook verschillende externe partijen gingen de BAG gebruiken,
zoals TomTom en Esri, een bekende softwareleverancier voor GIS (Geografische
Informatiesysteem). Met de komst van API's kwam het gebruik van de BAG in een
stroomversnelling.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="verschillende-wegen-naar-dezelfde-data">Verschillende wegen naar dezelfde data<a href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen#verschillende-wegen-naar-dezelfde-data" class="hash-link" aria-label="Direct link naar Verschillende wegen naar dezelfde data" title="Direct link naar Verschillende wegen naar dezelfde data" translate="no">​</a></h2>
<p>Janette Storm, productmanager BAG bij het Kadaster, is al sinds de invoering van
de wet BAG in 2009 betrokken bij deze basisregistratie. De BAG werd in die tijd
vooral gebruikt via bestanden en via een voorloper van de huidige webapplicatie
BAG-Viewer. "Als je destijds een losse vraag wilde stellen, dan deed je dat in
de BAG-Viewer. Als je veel administratieve data wilde hebben, dan haalde je
gewoon het hele bestand op. Er zijn nog steeds gebruikers die dat elke maand
doen", vertelt Storm. Er was ook een zogeheten SOAP-webservice beschikbaar
waarmee je gegevens in XML-formaat kon opvragen, maar deze was volgens Storm
best bewerkelijk om te implementeren. Dit bleek beter te kunnen met API's.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="een-gouden-toevalstreffer">Een gouden toevalstreffer<a href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen#een-gouden-toevalstreffer" class="hash-link" aria-label="Direct link naar Een gouden toevalstreffer" title="Direct link naar Een gouden toevalstreffer" translate="no">​</a></h2>
<p>Rond 2017 werkte het Kadaster aan een dataplatform op basis van linked data. De
BAG-API ontstond volgens Storm eigenlijk als bijproduct van dit project. Ze
vertelt hierover: "De techneuten gaven aan dat we de gegevens ook vrij makkelijk
via een API konden publiceren. Daar was interesse in, maar dan wilden we het ook
meteen goed doen: volgens de geldende API-standaarden, een goede manier van
publiceren en makkelijk toegankelijke specificaties."</p>
<p>Die aanpak bleek ontzettend succesvol. Binnen een paar maanden nadat de BAG-API
live ging, kreeg deze al net zoveel aanroepen als de SOAP-webservice, die op dat
moment al meer dan acht jaar in gebruik was. Geïnteresseerde eindgebruikers
wisten de API zelf te vinden en vroegen om aansluiting. Als bijzondere opsteker
won het Kadaster er in 2019 de Gouden API mee, de prijs voor de beste
overheids-API.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="van-bijproduct-naar-eindproduct">Van bijproduct naar eindproduct<a href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen#van-bijproduct-naar-eindproduct" class="hash-link" aria-label="Direct link naar Van bijproduct naar eindproduct" title="Direct link naar Van bijproduct naar eindproduct" translate="no">​</a></h2>
<p>Vlak na de introductie van de API volgde een grote herziening van de BAG. Storm:
"Dat was ook het moment om te kijken welke dataproducten we moesten laten
bestaan, welke een upgrade moesten krijgen en wat we hetzelfde moesten houden.
De eerste reactie vanuit de gebruikers was dat ze alles wilden behouden én dat
er behoefte was aan een API." Het eerste wat opviel was dat veel gebruikers nog
niet wisten dat er al een API was. Voor Storm was dit het signaal om de BAG-API
van bijproduct naar een eindproduct te brengen en de oude SOAP-webservice niet
verder te ontwikkelen.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="kijken-met-de-bril-van-de-eindgebruiker">Kijken met de bril van de eindgebruiker<a href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen#kijken-met-de-bril-van-de-eindgebruiker" class="hash-link" aria-label="Direct link naar Kijken met de bril van de eindgebruiker" title="Direct link naar Kijken met de bril van de eindgebruiker" translate="no">​</a></h2>
<p>Bij versie 2 van de BAG-API verschoof de focus van pure technische ontsluiting
naar een betere bruikbaarheid voor de eindgebruiker. Met haar achtergrond als
industrieel ontwerper weet Storm als geen ander dat bruikbaarheid de sleutel is
tot succes. "Een belangrijke stap was om te kijken welke informatie de
eindgebruiker daadwerkelijk nodig heeft. Wat we dus bijvoorbeeld bij versie 2
van de API hebben gedaan, is dat je niet alleen een adres kan opvragen, maar ook
de eigenschappen die bij dat adres horen. Dit was bij de eerste versie van de
API een hoop gepuzzel", vertelt Storm.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="geen-gepuzzel-meer">Geen gepuzzel meer<a href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen#geen-gepuzzel-meer" class="hash-link" aria-label="Direct link naar Geen gepuzzel meer" title="Direct link naar Geen gepuzzel meer" translate="no">​</a></h2>
<p>Toen versie 2 van de BAG-API, de BAG API Individuele Bevragingen (IB), uitkwam,
nam het gebruik opnieuw een enorme vlucht. Ondanks dit nieuwe succes maakte niet
iedere gebruiker het meest efficiënte gebruik van de BAG-API. Storm noemt als
voorbeeld een ontwikkelaar die duizenden losse bevragingen deed voor
adresgegevens per pand, omdat hij niet wist dat er een efficiëntere,
samengestelde route bestond. Zulke pieken in het dataverkeer zijn voor het
Kadaster reden om contact op te nemen met gebruikers, en dat leverde een
interessant patroon op: veel van dit soort problemen bleken terug te voeren op
hoe de documentatie was opgebouwd. Veel gebruikers volgden die top-down, terwijl
de meest bruikbare functionaliteit onderaan stond. Storm: "Toen hebben we de
documentatie daarop aangepast. Nu staat de functionaliteit die het handigst is
om te gebruiken bovenaan. Deze functies werden toen al het meest gebruikt, en nu
nog steeds. 90% van de aanvragen is namelijk samengestelde informatie."</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-volgende-stap">De volgende stap<a href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen#de-volgende-stap" class="hash-link" aria-label="Direct link naar De volgende stap" title="Direct link naar De volgende stap" translate="no">​</a></h2>
<p>Het Kadaster staat op dit moment voor een verplichte technische wijziging in de
backend. Voor Storm reden om gelijk verder te kijken, want de tweede versie van
de API is inmiddels ook al meer dan vijf jaar oud. Voor versie 3 van de API gaat
het deze keer niet zozeer om ingrijpende wijzigingen. "We hebben heel lang
gezegd: we moeten het zo ontwerpen dat het product aansluit bij de vraag. Nu zeg
ik eigenlijk: dat lukt best wel goed, maar we willen de kans dat je de data echt
goed kan gebruiken nog groter maken", vertelt Storm. "Functioneel zal het
bijvoorbeeld makkelijker worden om ook de historie, historische informatie, op
te vragen. En dat alles zoveel mogelijk via hetzelfde endpoint gaat, zodat je
niet op iets anders hoeft aan te sluiten om aan deze gegevens te komen."</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="ook-geografische-data-delen-via-apis">Ook geografische data delen via API's<a href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen#ook-geografische-data-delen-via-apis" class="hash-link" aria-label="Direct link naar Ook geografische data delen via API's" title="Direct link naar Ook geografische data delen via API's" translate="no">​</a></h2>
<p>Naast de BAG-API IB werkt het Kadaster ook aan andere manieren om de BAG-data
via API's te ontsluiten. Dit jaar is bijvoorbeeld de BAG OGC Features API
gelanceerd. Deze API is gericht op bevragingen van de BAG door GIS-specialisten;
de geografische informatie staat centraal in plaats van de administratieve
gegevens van het object.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="samenwerken-aan-betere-overheids-apis">Samenwerken aan betere overheids-API's<a href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen#samenwerken-aan-betere-overheids-apis" class="hash-link" aria-label="Direct link naar Samenwerken aan betere overheids-API's" title="Direct link naar Samenwerken aan betere overheids-API's" translate="no">​</a></h2>
<p>De ontwikkeling van de BAG-API staat niet op zichzelf. Samen met andere partijen
werkt het Kadaster in het
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/communities/kennisplatform-apis">Kennisplatform API's</a>
aan gezamenlijke standaarden voor overheids-API's, waaronder de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules">API Design Rules</a>.
"We willen dat onze API-ontwikkeling afgestemd is met het kennisplatform, zodat
we allemaal dezelfde richting opgaan", vertelt Storm. Om deze aanpak te
stimuleren, reikt het kennisplatform elk jaar de Gouden API uit: de prijs voor
de beste overheids-API van dat jaar. Dit jaar ligt de focus op de implementatie
van diverse API's. Storm: "Als je kijkt naar de BAG-Viewer, dan is dat een goed
voorbeeld. Het is de implementatie van de BAG-API IB, de BAG OGC API's en
bijvoorbeeld ook de Terugmeldings-API." Het Kadaster laat hiermee zien dat het
niet alleen goede API's bouwt, maar ze ook zelf weet te combineren tot
waardevolle applicaties.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="productgericht-blijven-ontwikkelen">Productgericht blijven ontwikkelen<a href="https://developer.overheid.nl/blog/2026/09/10/bag-api-productgericht-ontwikkelen#productgericht-blijven-ontwikkelen" class="hash-link" aria-label="Direct link naar Productgericht blijven ontwikkelen" title="Direct link naar Productgericht blijven ontwikkelen" translate="no">​</a></h2>
<p>In veel opzichten is de BAG-API een rolmodel geweest voor andere overheids-API's
en valt er veel te leren uit de aanpak van het Kadaster. Storm: "De focus van
technische ontsluiting naar productgericht ontwikkelen, is denk ik een stap die
op veel plekken in de overheid nog wel gemaakt moet worden. En door zichtbaar te
maken van wat goed werkt, kun je ook anderen inspireren en stimuleren."</p>]]></content>
        <author>
            <name>Kennisplatform API's</name>
        </author>
        <category label="API" term="API"/>
        <category label="API Design" term="API Design"/>
        <category label="API Design Rules" term="API Design Rules"/>
        <category label="Gouden API" term="Gouden API"/>
        <category label="Kennisplatform API's" term="Kennisplatform API's"/>
        <category label="Geodata" term="Geodata"/>
        <category label="Open Geospatial Consortium" term="Open Geospatial Consortium"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL onder de loep (deel 4): wanneer wel, en wanneer niet?]]></title>
        <id>https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader</id>
        <link href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader"/>
        <updated>2026-09-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[In het slotdeel van deze serie brengen we alles samen: wanneer is GraphQL
een logische keuze en wanneer ben je met REST beter af? We schetsen een
afwegingskader langs zeven factoren, kijken hoe grote API-aanbieders kiezen,
plaatsen de afweging in de Nederlandse overheidscontext en zetten op een rij
wat de keuze voor GraphQL vraagt.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="GraphQL onder de loep" src="https://developer.overheid.nl/assets/images/graphql-onder-de-loep-e07384148936c384d21d833215dd432c.jpg" width="1731" height="909" class="img_rVHu"></p>
<p>In de eerste drie delen van deze serie hebben we GraphQL leren kennen als een
getypeerde querytaal met een fundamenteel ander model dan REST
(<a class="" href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie">deel 1</a>), zagen we dat de flexibele
bevraging zowel de grote kracht als een serieuze beheeropgave is
(<a class="" href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten">deel 2</a>) en liepen we
zes ontwerpuitdagingen langs die in de praktijk bepalen hoeveel werk een
GraphQL-API werkelijk kost
(<a class="" href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp">deel 3</a>).</p>
<p>In dit slotdeel komen we bij de vraag waar het allemaal om draait: wanneer is
GraphQL een passende keuze, en wanneer ben je met REST beter af? Er zijn
omstandigheden waarin het ene model aantoonbaar beter past dan het andere.</p>
<div class="theme-admonition theme-admonition-info admonition_jS7q alert alert--info"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>GraphQL onder de loep</div><div class="admonitionContent_ZZhP"><p>Dit artikel is deel 4 van een vierdelige serie:</p><ol>
<li class=""><a class="" href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie">Een kennismaking</a></li>
<li class=""><a class="" href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten">Flexibel bevragen, en wat dat kost</a></li>
<li class=""><a class="" href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp">Zes uitdagingen bij schema-ontwerp</a></li>
<li class="">Wanneer wel, en wanneer niet? (dit deel)</li>
</ol></div></div>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>De keuze hangt af van zeven factoren: wie je afnemers zijn, of je in een context
werkt waar een vastgesteld kader telt, hoe belangrijk HTTP-caching is, hoe je
datamodel eruitziet, hoeveel verschillende bevragingen je verwacht, hoeveel
beheercapaciteit je hebt en hoe omkeerbaar de keuze moet zijn. Bij publieke
overheids-API's wijzen die vaak dezelfde kant op en is REST het uitgangspunt. De
ADR gelden alleen als je REST aanbiedt: kies je GraphQL, dan mis je een
vastgesteld kader en een toetsing, en hoef je tegelijk niets uit te leggen. Voor
Nederlandse overheidsorganisaties is GraphQL vooral kansrijk waar de afnemers
bekend zijn: als laag boven de bronnen, bijvoorbeeld een backend-for-frontend of
een orkestratielaag, of als toegang tot een intern of afgeschermd model. Kies je
ervoor, dan is de lijst aan het eind van dit artikel wat je zelf inricht en
vastlegt.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="het-afwegingskader">Het afwegingskader<a href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader#het-afwegingskader" class="hash-link" aria-label="Direct link naar Het afwegingskader" title="Direct link naar Het afwegingskader" translate="no">​</a></h2>
<p>De uitdagingen uit deel 2 en 3 vormen de opgave die GraphQL met zich meebrengt.
De vraag is per situatie of die opgave in verhouding staat tot wat je ervoor
terugkrijgt. Zeven factoren helpen bij die afweging. Sommige gaan over
omstandigheden die je niet zelf in de hand hebt, andere over hoeveel werk je
erin wil stoppen; hoe zwaar ze wegen, hangt van je situatie af.</p>
<table><thead><tr><th>Factor</th><th>Wijst richting GraphQL</th><th>Wijst richting REST</th></tr></thead><tbody><tr><td><strong>Afnemers</strong></td><td>Clients waarmee je direct kunt afstemmen en die hun vragen zelf samenstellen: eigen apps en portalen, teams in de eigen organisatie, een besloten groep ontwikkelaars</td><td>Anonieme of onbekende afnemers, publieke open data, en formele koppelingen tussen organisaties</td></tr><tr><td><strong>Kader</strong></td><td>Interne of afgebakende context waarin eigen conventies volstaan</td><td>Ketenverkeer of een landelijke voorziening, waar een vastgesteld kader telt</td></tr><tr><td><strong>Caching</strong></td><td>Caching aan de clientkant, of via persisted queries met <code>GET</code> te organiseren</td><td>Zwaar leunen op HTTP- en CDN-caching, zoals bij veelbevraagde open data</td></tr><tr><td><strong>Datamodel</strong></td><td>Sterk samenhangende graph met veel relaties die per scherm anders doorlopen wordt</td><td>Overzichtelijke, afgebakende resources met voorspelbare toegangspatronen</td></tr><tr><td><strong>Bevragingen</strong></td><td>Talrijk, snel wisselend en door de clientteams zelf bedacht</td><td>Een stabiele, overzichtelijke set gegevensvragen</td></tr><tr><td><strong>Beheersing</strong></td><td>Capaciteit om cost analysis, autorisatie per veld of per operatie en monitoring per operatie te doen</td><td>Behoefte aan een eenvoudig te beveiligen en te begrenzen API-oppervlak</td></tr><tr><td><strong>Omkeerbaarheid</strong></td><td>Eén team of domein, waar een latere migratie te overzien is</td><td>Lange levensduur, meerdere leveranciers, wisselend opdrachtnemerschap</td></tr></tbody></table>
<p>De kolommen sluiten elkaar niet uit. GraphQL en REST kunnen naast elkaar
bestaan, elk voor het deel van het landschap waar ze sterk zijn. Bij publieke
overheids-API's wijzen de eerste drie rijen vaak dezelfde kant op, en dan is
REST het uitgangspunt. Vaak is niet altijd: bedien je clients waarmee je direct
kunt afstemmen, buiten het ketenverkeer en zonder cachingafhankelijkheid, dan
komt de afweging er anders uit, en blijven de vier andere rijen te beantwoorden.</p>
<p>Vier rijen verdienen een toelichting.</p>
<p><strong>Afnemers.</strong> Het beheersapparaat uit deel 2 gaat uit van afnemers die je kunt
identificeren: kostenbudgetten per afnemer, vooraf geregistreerde operaties,
monitoring per client. Bij anonieme afnemers vervalt die aanname en moeten de
generieke limieten al het werk doen, zonder onderscheid tussen een afnemer die
zich vergist en een afnemer die het erom doet.</p>
<p>Bekend is hier niet hetzelfde als gecontracteerd. Ook ketenverkeer loopt tussen
bekende partijen, bijvoorbeeld via FSC, maar daar liggen de koppelingen vast in
afspraken per organisatie, gaat het om een stabiele set gegevensvragen en hoort
er een verantwoordingsplicht bij. Die situatie wijst richting REST, zoals de
sectie over de overheidscontext hieronder uitwerkt. Deze rij gaat over afnemers
met wie je in hetzelfde ontwikkelritme zit en die hun vragen zelf willen
samenstellen.</p>
<p><strong>Kader.</strong> Hier speelt een misverstand. Het functioneel toepassingsgebied van de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules">REST API Design Rules</a>
is "het aanbieden van REST API's", en Forum Standaardisatie stelt er expliciet
bij dat de standaard "niet het gebruik van REST-API's verplicht". Kies je
GraphQL, dan val je dus buiten het toepassingsgebied: je mist een vastgesteld
kader en de bijbehorende toetsing, zoals de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/tools/api-design-rules-linter">ADR Checker</a> die
een OpenAPI-document tegen de regels houdt, en hoeft tegelijk niets uit te
leggen. Voor een API die je eigen frontend bedient is dat weinig bezwaar; in
ketenverkeer of als landelijke voorziening is het de kern van de afweging.</p>
<p><strong>Bevragingen.</strong> Tel je bevragingen, en vraag wie ze definieert. Een stabiele
set gegevensvragen laat zich prima als toegesneden endpoints of
informatieproducten aanbieden, en dat is standaardconform. Een generiek
querymechanisme betaalt zich terug wanneer de vragen talrijk zijn, snel wisselen
en door de clientteams zelf worden bedacht. Zet je die vragen vervolgens vast
als geregistreerde operaties (de persisted queries uit deel 2), dan heb je
feitelijk weer endpoints, met dit verschil: de clientteams definiëren ze zelf,
zonder wijziging aan de backend.</p>
<p><strong>Omkeerbaarheid.</strong> Deze ontbreekt in de meeste afwegingen en is voor de
overheid juist relevant. Deel 3 liet zien dat het dialect voor filtering en
sortering per framework verschilt en daarmee in je publieke contract landt, en
dat custom scalars server en client aan dezelfde library binden. Het contract
erft daarmee eigenschappen van de implementatie, wat een latere migratie of
leverancierswissel duurder maakt. Houd je schema daarom technologieneutraal en
laat het dialect niet naar buiten lekken. Dat is ook waar de leidraad
<a class="" href="https://developer.overheid.nl/kennisbank/leidraad/open-standaarden">Gebruik open standaarden</a> op aandringt:
leveranciersonafhankelijkheid begint bij een contract dat niet aan één
implementatie vastzit.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="hoe-grote-aanbieders-kiezen">Hoe grote aanbieders kiezen<a href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader#hoe-grote-aanbieders-kiezen" class="hash-link" aria-label="Direct link naar Hoe grote aanbieders kiezen" title="Direct link naar Hoe grote aanbieders kiezen" translate="no">​</a></h2>
<p>Dat de afweging echt twee kanten op kan vallen, laat de praktijk van grote
API-aanbieders zien.</p>
<p><strong>Shopify</strong> ging volledig over:
<a href="https://www.shopify.com/partners/blog/all-in-on-graphql" target="_blank" rel="noopener noreferrer" class="">de REST Admin API is sinds oktober 2024 legacy</a>
en nieuwe publieke apps in de App Store
<a href="https://shopify.dev/changelog/starting-april-2025-new-public-apps-submitted-to-shopify-app-store-must-use-graphql" target="_blank" rel="noopener noreferrer" class="">moeten sinds april 2025 GraphQL gebruiken</a>.
Duizenden bekende, geregistreerde app-ontwikkelaars met sterk uiteenlopende
databehoeften op één samenhangend commerce-datamodel, en de schaal om cost-based
rate limiting (zie deel 2) als platformvoorziening aan te bieden.</p>
<p><strong>Netflix</strong> draait intern
<a href="https://www.infoq.com/articles/federated-GraphQL-platform-Netflix/" target="_blank" rel="noopener noreferrer" class="">federated graphs over ruim tweehonderd services</a>:
supergraphs, samengesteld uit de deelschema's van evenzoveel teams, met
volledige controle over alle clients.</p>
<p><strong>GitHub</strong> biedt al jaren
<a href="https://docs.github.com/en/rest/about-the-rest-api/comparing-githubs-rest-api-and-graphql-api" target="_blank" rel="noopener noreferrer" class="">REST en GraphQL naast elkaar aan</a>
en adviseert afnemers te kiezen wat bij hun gebruik en ervaring past: REST
vanwege de vertrouwde HTTP-conventies, GraphQL wanneer één query het werk van
meerdere REST-requests moet doen.</p>
<p>Tegelijk klinkt er ook kritiek uit de praktijk. Matt Bessey vatte in
<a href="https://bessey.dev/blog/2024/05/24/why-im-over-graphql/" target="_blank" rel="noopener noreferrer" class="">Why, after 6 years, I'm over GraphQL</a>
samen waarom hij na zes jaar GraphQL voor nieuw werk weer een OpenAPI-gebaseerde
REST-API adviseert: het beveiligings- en performance-oppervlak uit deel 2 bleek
in de praktijk duurder dan de flexibiliteitswinst. Marc-André Giroux, die
jarenlang aan de API-platformen van GitHub en Netflix werkte, komt in
<a href="https://magiroux.com/eight-years-of-graphql" target="_blank" rel="noopener noreferrer" class="">Why, after 8 years, I still like GraphQL sometimes in the right context</a>
tot een voorwaardelijk ja: GraphQL loont bij veel bekende clients en een rijk
datamodel, en is overkill daarbuiten.</p>
<p>Deze verhalen spreken elkaar niet tegen: de uitkomst volgt telkens uit de
context, niet uit de technologie. Belangrijk is dan wel welke context dat is.
Het zijn platformen met duizenden geregistreerde ontwikkelaars op één
commercieel datamodel, met een platformteam dat limieten en schemabeheer als
product aanbiedt. Geen van hen is een publieke registratie met een wettelijke
taak en een verantwoordingsplicht over inzage. En binnen de Nederlandse overheid
is de bewijsbasis dun: breed gedeelde ervaringsverhalen zijn er nauwelijks. Weeg
deze casussen dus op overdraagbaarheid naar jouw situatie, niet op autoriteit.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-nederlandse-overheidscontext">De Nederlandse overheidscontext<a href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader#de-nederlandse-overheidscontext" class="hash-link" aria-label="Direct link naar De Nederlandse overheidscontext" title="Direct link naar De Nederlandse overheidscontext" translate="no">​</a></h2>
<p>Voor overheidsorganisaties speelt naast de technische afweging een
standaardenafweging.</p>
<p>De
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules">REST API Design Rules</a>
staan sinds 2020 op de
<a href="https://www.forumstandaardisatie.nl/open-standaarden/rest-api-design-rules" target="_blank" rel="noopener noreferrer" class="">'pas toe of leg uit'-lijst</a>
van het Forum Standaardisatie en zijn expliciet gescoped op REST-API's. De
<a href="https://docs.geostandaarden.nl/api/API-Strategie/" target="_blank" rel="noopener noreferrer" class="">API Strategie van de Nederlandse overheid</a>
noemt GraphQL alleen zijdelings als mogelijke query style. Er is dus geen
NLGov-profiel, geen toetsingskader en geen vastgestelde set conventies: wat de
ADR voor REST-API's dichtregelen, zou per organisatie opnieuw worden
uitgevonden, met interoperabiliteitsrisico's van dien, terwijl deel 3 liet zien
dat juist die conventies (paginering, filtering, foutafhandeling, en zelfs het
ankerpunt voor autorisatie) bij GraphQL niet vanzelf meekomen. De vraag hoe de
ADR zich verhouden tot alternatieven zoals GraphQL staat binnen het
<a href="https://github.com/Geonovum/KP-APIs/issues/537" target="_blank" rel="noopener noreferrer" class="">Kennisplatform API's</a> al langer
op de agenda, en werd in juni 2026 opnieuw opgepakt. Het
<a class="" href="https://developer.overheid.nl/blog/2025/06/18/het-nieuwe-api-register">API-register</a> op deze site is om die
reden REST-only: GraphQL heeft potentie, maar verdient pas een eigen plek bij
bredere adoptie en standaardisatie.</p>
<p>Naast het API-ontwerp is er de verbindingenkant:
<a class="" href="https://developer.overheid.nl/kennisbank/devops/standaarden/fsc">FSC</a> (Federated Service Connectivity),
verplicht onderdeel van het
<a href="https://gitdocumentatie.logius.nl/publicatie/dk/restapi/" target="_blank" rel="noopener noreferrer" class="">Digikoppeling REST API-profiel</a>,
sinds april 2026 in versie 2.0. De
<a href="https://gitdocumentatie.logius.nl/publicatie/fsc/core/2.0.0/" target="_blank" rel="noopener noreferrer" class="">FSC-specificatie</a>
definieert een service als "An HTTP API offered to the Group" en stelt geen
eisen aan de API-stijl, dus technisch kan GraphQL erop, maar inhoudelijk wringt
de granulariteit. Contracten autoriseren een service als geheel en het
<a href="https://gitdocumentatie.logius.nl/publicatie/fsc/logging/1.1.0/" target="_blank" rel="noopener noreferrer" class="">transactielog</a>
registreert per request welke service is bevraagd. Een REST-landschap laat zich
opdelen per resource of gegevensdomein; een GraphQL-API is in de praktijk één
service. Contracten worden daarmee alles-of-niets, en de vraag welke gegevens
zijn ingezien is alleen in de GraphQL-laag te beantwoorden. Die
verantwoordingsopgave organiseer je dus zelf, en het per-operatie-anker uit deel
3 is daarvoor de kansrijkste route: een vastgezette set geregistreerde operaties
laat zich per stuk autoriseren en loggen, met het
<a class="" href="https://developer.overheid.nl/kennisbank/data/standaarden/logboek-dataverwerkingen">Logboek Dataverwerkingen</a>
als kader voor de vastlegging. Dat gebeurt dan wel buiten de contracten en het
transactielog van FSC om.</p>
<div class="language-text codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-text codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token plain">REST-landschap op FSC          GraphQL op FSC</span><br></div><div class="token-line"><span class="token plain">├─ vergunningen (contract A)   └─ graphql (één contract:</span><br></div><div class="token-line"><span class="token plain">├─ dossiers     (contract B)      alles-of-niets)</span><br></div><div class="token-line"><span class="token plain">└─ documenten   (contract C)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="waar-graphql-wél-past-binnen-de-overheid">Waar GraphQL wél past binnen de overheid<a href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader#waar-graphql-w%C3%A9l-past-binnen-de-overheid" class="hash-link" aria-label="Direct link naar Waar GraphQL wél past binnen de overheid" title="Direct link naar Waar GraphQL wél past binnen de overheid" translate="no">​</a></h2>
<p>Betekent dit dat GraphQL binnen de overheid geen plaats heeft? Nee. Het betekent
wel dat GraphQL vooralsnog niet de gestandaardiseerde, publieke API-laag zelf
vervangt, maar kansrijk is waar de afnemers bekend zijn, want dan valt het
aanvalsoppervlak uit deel 2 grotendeels weg: als laag boven de bronnen, of als
toegang tot een intern of afgeschermd model. Het eerste schematisch:</p>
<!-- -->
<p>Concreet zien we twee patronen:</p>
<ul>
<li class=""><strong>Een laag boven bestaande bronnen.</strong> In de kleinste vorm een
backend-for-frontend: een GraphQL-laag die voor de eigen portalen en apps data
uit meerdere (REST-)bronnen samenbrengt, met clients die bekend zijn en in
eigen beheer. In de bredere vorm een orkestratielaag die gegevens uit meerdere
API's in samenhang aanbiedt aan meerdere afnemers, zonder die bronnen te
vervangen. Het Nederlandse voorbeeld daarvan is
<a href="https://federatief.datastelsel.nl/kennisbank/imx/" target="_blank" rel="noopener noreferrer" class="">IMX</a> van Geonovum:
model-gedreven orkestratie waarbij een doelmodel (het informatieproduct) wordt
gemapt op bestaande bronregistraties. GraphQL zit daar vooral onder de
motorkap: het georkestreerde informatieproduct kan ook als REST-API worden
ontsloten, en de bronnen blijven gewone, ADR-conforme REST-API's of OGC API's.</li>
<li class=""><strong>Toegang tot één samenhangend model.</strong> Veel bekende afnemers die
uiteenlopende en wisselende vragen stellen: interne teams in een groot
datalandschap, waar de federated aanpak van Netflix als voorbeeld kan dienen,
of externe afnemers die zich registreren en verkennende, analytische
bevragingen doen op rijke datasets, vergelijkbaar met de analytische use cases
waar we bij <a class="" href="https://developer.overheid.nl/blog/2025/10/21/odata-en-de-rest-api-design-rules">OData</a>
dezelfde grens trokken: onderzoek en zelfbediening op datasets, niet het
primaire kanaal voor wettelijke gegevensverstrekking. Hier is GraphQL niet de
laag boven de bronnen maar de toegang tot het model zelf, en gelden de rijen
Bevragingen en Beheersing uit het afwegingskader in volle omvang.</li>
</ul>
<p>Bij het eerste patroon hoort een voorbehoud: een extra laag is een extra
contractvlak. Betekenis, autorisatie en logging moeten daar opnieuw worden
waargemaakt, en bij model-gedreven orkestratie is de mapping zelf de plek waar
semantiek kan sneuvelen. Wat je wint aan gemak voor de afnemer, organiseer je
erbij aan beheer. Dat is niet nieuw en niet GraphQL-specifiek: we schreven
eerder over
<a class="" href="https://developer.overheid.nl/blog/2023/11/28/de-uitdagingen-bij-api-orkestratie">de uitdagingen bij API-orkestratie</a>.</p>
<p>Voor publieke API's met anonieme afnemers, open data met zware caching, en voor
ketenverkeer, landelijke voorzieningen en andere ontsluiting waar de conventies
tussen organisaties vast moeten liggen, blijft REST de logische keuze.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="wat-de-keuze-voor-graphql-vraagt">Wat de keuze voor GraphQL vraagt<a href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader#wat-de-keuze-voor-graphql-vraagt" class="hash-link" aria-label="Direct link naar Wat de keuze voor GraphQL vraagt" title="Direct link naar Wat de keuze voor GraphQL vraagt" translate="no">​</a></h2>
<p>Valt de afweging naar GraphQL, dan is dit de inrichting die deel 2 en 3
opleveren. Omdat er geen profiel is dat dit voor je regelt, is dezelfde lijst
ook wat je zelf vastlegt en publiceert, richting je eigen architectuurboard, je
security review en je afnemers.</p>
<table><thead><tr><th>Wat</th><th>Waarom</th></tr></thead><tbody><tr><td>Depth en amount limits</td><td>Voorkomt dat een paar regels querytekst miljoenen rijen raakt (deel 2)</td></tr><tr><td>Query cost analysis</td><td>Maakt de zwaarte van een request begrensbaar in plaats van onbekend</td></tr><tr><td>Geregistreerde operaties</td><td>Begrenst, maakt cachebaar en maakt autorisatie per operatie mogelijk</td></tr><tr><td>Ankerpunt voor autorisatie</td><td>Per veld of per operatie, plus de gegevensafhankelijke checks eronder</td></tr><tr><td>Monitoring per operatie</td><td>Zonder dit is optimaliseren en uitfaseren blind werk</td></tr><tr><td>Cachingstrategie</td><td>Client, server of persisted queries met <code>GET</code>, maar wel een expliciete keuze</td></tr><tr><td>Eigen conventies, publiek</td><td>Paginering, filtering, fouten en scalars vastleggen en documenteren</td></tr><tr><td>Technologieneutraal schema</td><td>Houdt het framework-dialect uit je publieke contract</td></tr></tbody></table>
<p>Deze acht punten zijn het minimum, geen bewijs dat GraphQL past. Ze maken je
eigen API beheersbaar, maar interoperabiliteit vraagt conventies die je met
anderen deelt, en die komen uit een profiel dat voor GraphQL niet bestaat. Die
vraag beantwoordt het afwegingskader hierboven. Autorisatie laat zich daarbij
het minst goed achteraf toevoegen, omdat het elk veld en elk pad door de graph
raakt (deel 3).</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="vooruitblik">Vooruitblik<a href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader#vooruitblik" class="hash-link" aria-label="Direct link naar Vooruitblik" title="Direct link naar Vooruitblik" translate="no">​</a></h2>
<p>De standaardisatie rond GraphQL beweegt, en dat is relevant voor deze afweging
op langere termijn. Wie de afweging over een of twee jaar opnieuw maakt, kan op
deze signalen letten:</p>
<ul>
<li class="">De
<a href="https://graphql.github.io/graphql-over-http/" target="_blank" rel="noopener noreferrer" class="">GraphQL over HTTP-specificatie</a>
wordt definitief: daarmee ligt het transportgedrag vast en wordt ondersteuning
door gateways en tooling betrouwbaarder.</li>
<li class="">De
<a href="https://github.com/graphql/graphql-over-http/blob/main/rfcs/PersistedOperations.md" target="_blank" rel="noopener noreferrer" class="">RFC voor persisted operations</a>
landt in die specificatie: dan is er één gestandaardiseerde vorm voor het
begrenzen, cachen en autoriseren van bevragingen, nu nog per implementatie
anders (deel 2 en 3).</li>
<li class="">IBM's <a href="https://ibm.github.io/graphql-specs/cost-spec.html" target="_blank" rel="noopener noreferrer" class="">cost-directives</a>
groeien uit tot een gedeelde taal voor querykosten, zodat limieten
interoperabel worden in plaats van servereigen.</li>
<li class="">De
<a href="https://github.com/graphql/composite-schemas-spec" target="_blank" rel="noopener noreferrer" class="">Composite Schemas-werkgroep</a>
levert een leveranciersneutrale federatiestandaard op, relevant voor
orkestratie over organisatiegrenzen en voor de omkeerbaarheid uit het
afwegingskader.</li>
<li class="">En dichter bij huis: de eerdergenoemde discussie binnen het Kennisplatform
API's leidt tot een standpunt of profiel, en GraphQL-API's verschijnen in
relevante aantallen in het API-register.</li>
</ul>
<p>Naarmate deze punten worden afgevinkt, verschuift de balans: een deel van wat je
nu zelf moet ontwerpen en bewaken, wordt dan door standaarden en tooling
gedragen. Het is dezelfde ontwikkeling die REST in de afgelopen tien jaar heeft
doorgemaakt, met de ADR als resultaat.</p>
<p>Het kan ook anders lopen. De RFC voor persisted operations ligt er al jaren, de
transportspecificatie is nog altijd een working draft, en het OpenAPI-ecosysteem
staat evengoed niet stil. Reken dus niet op standaardisatie die er nog niet is:
de afweging die je vandaag maakt, moet standhouden op wat vandaag vastligt.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="werkgroep-graphql">Werkgroep GraphQL<a href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader#werkgroep-graphql" class="hash-link" aria-label="Direct link naar Werkgroep GraphQL" title="Direct link naar Werkgroep GraphQL" translate="no">​</a></h2>
<p>Op die standaardisatie hoeft de overheid niet passief te wachten. Voor
asynchrone API's doorloopt de
<a class="" href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe">werkgroep AsyncAPI</a> op dit moment een
verkenningstraject; een vergelijkbare werkgroep voor GraphQL zou nu al aan de
slag kunnen.</p>
<p>De eerste taak is dan niet het schrijven van regels, maar het definiëren van het
toepassingsgebied, en dat is minder triviaal dan het lijkt. De ADR gelden voor
"het aanbieden van REST API's" en de OAS voor "het beschrijven/specificeren van
een REST API": beide zijn gescoped op de techniek. Daarmee regelen ze hoe je
iets bouwt zodra de keuze gemaakt is, en niet wanneer die keuze passend is. Een
GraphQL-profiel met "het aanbieden van GraphQL API's" als toepassingsgebied
herhaalt die cirkel, en dan valt de keuze tussen de twee opnieuw tussen de
kaders in. Wie dat wil doorbreken, moet het toepassingsgebied formuleren in
termen van de opgave in plaats van de technologie: naar het soort afnemers, of
naar het soort ontsluiting. Dat is precies de vraag die bij het Kennisplatform
op de agenda staat, en ze is lastiger dan het opschrijven van conventies.</p>
<p>Pas daarna komen de regels in beeld, en die inhoudsopgave ligt in deze serie al
klaar: van limieten en caching in deel 2 tot paginering, foutafhandeling en het
ankerpunt voor autorisatie in deel 3, precies de onderdelen waar de ADR dit voor
REST-API's al regelen.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="slotadvies">Slotadvies<a href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader#slotadvies" class="hash-link" aria-label="Direct link naar Slotadvies" title="Direct link naar Slotadvies" translate="no">​</a></h2>
<p>GraphQL is een volwassen technologie die een reëel probleem oplost: het flexibel
bedienen van veel verschillende, bekende clients vanuit één samenhangend
datamodel. Wie in die situatie zit en bereid is de bijbehorende beheer- en
ontwerpopgave serieus te nemen, heeft aan GraphQL een krachtig instrument, ook
binnen de overheid, bijvoorbeeld als backend-for-frontend of in een intern
datalandschap.</p>
<p>Voor publieke overheids-API's ligt dat anders. Daar wegen de sterke punten van
REST (eenvoud, HTTP-native caching, de route als ankerpunt voor autorisatie,
content negotiation) zwaar, en bieden de ADR een vastgesteld, getoetst kader dat
voor GraphQL vooralsnog ontbreekt. Niet omdat GraphQL slechter is, maar omdat de
context er (nog) niet naar is. De ADR maken die keuze niet voor je, want ze
gelden alleen als je REST aanbiedt. Wie GraphQL kiest hoeft dus niets uit te
leggen, maar stapt wel buiten een vastgesteld kader en belegt de acht punten
hierboven zelf. Voor het bedienen van de eigen frontends is GraphQL een serieuze
optie om te verkennen. En wie over een paar jaar opnieuw kijkt, loopt de zeven
factoren nog eens langs: staat er dan een profiel, dan verandert vooral de rij
"Kader", en dat is het echte nieuws.</p>
<p>Een compacte referentie over GraphQL, met de status binnen de overheid en de
belangrijkste specificaties, staat in de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/graphql">kennisbank</a>.</p>]]></content>
        <author>
            <name>Joost Farla</name>
        </author>
        <category label="API" term="API"/>
        <category label="API Design" term="API Design"/>
        <category label="GraphQL" term="GraphQL"/>
        <category label="REST API design" term="REST API design"/>
        <category label="API Design Rules" term="API Design Rules"/>
        <category label="Adoptie" term="Adoptie"/>
        <category label="Orkestratie" term="Orkestratie"/>
        <category label="FSC" term="FSC"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[De Beslisboom Open Standaarden: welke standaarden gelden voor jouw project?]]></title>
        <id>https://developer.overheid.nl/blog/2026/08/26/beslisboom-open-standaarden</id>
        <link href="https://developer.overheid.nl/blog/2026/08/26/beslisboom-open-standaarden"/>
        <updated>2026-08-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Je bouwt aan een nieuwe applicatie, koppelt systemen via API's of werkt aan
een voorziening voor de overheid. Ergens onderweg komt de vraag langs: welke
open standaarden moet je hier toepassen? De Beslisboom Open Standaarden geeft
in zes stappen antwoord.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="Beslisboom Open Standaarden" src="https://developer.overheid.nl/assets/images/beslisboom-open-standaarden-9617d31927586bdccf3de0933dac2e5c.png" width="1280" height="720" class="img_rVHu"></p>
<p>Je bouwt aan een nieuwe applicatie, koppelt systemen via API's of werkt aan een
voorziening voor de overheid. En ergens onderweg komt de vraag langs: welke open
standaarden moet ik hier nu eigenlijk toepassen? Ze zijn niet vrijblijvend. Voor
publieke organisaties zorgen open standaarden voor interoperabiliteit,
leveranciersonafhankelijkheid, veiligheid, datakwaliteit en toegankelijkheid.
Precies de dingen die bepalen of jouw software straks soepel samenwerkt met de
rest van het overheidslandschap.</p>
<p>Het lastige is alleen: de standaarden zíjn er, de afspraken zíjn helder, maar
uitzoeken wélke gelden voor jouw specifieke applicatie kost tijd die je liever
in code steekt. Daardoor blijft de toepassing in de praktijk achter, niet uit
onwil maar uit gedoe.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-beslisboom-open-standaarden">De Beslisboom Open Standaarden<a href="https://developer.overheid.nl/blog/2026/08/26/beslisboom-open-standaarden#de-beslisboom-open-standaarden" class="hash-link" aria-label="Direct link naar De Beslisboom Open Standaarden" title="Direct link naar De Beslisboom Open Standaarden" translate="no">​</a></h2>
<p>Voor dat moment is er de Beslisboom Open Standaarden van Forum Standaardisatie.
In zes stappen kom je tot een gerichte selectie van de standaarden die voor jouw
project relevant zijn. Je loopt de vragen door en ziet meteen welke standaarden
ertoe doen.</p>
<p>Het resultaat is geen afvinklijstje, maar een onderbouwde set die je direct kunt
vertalen naar je ontwerp, je backlog of je gesprek met de architect of
leverancier. Een paar minuten werk aan het begin scheelt later een hoop
refactoren en discussie.</p>
<p><a href="https://www.forumstandaardisatie.nl/video-beslisboom-open-standaarden" target="_blank" rel="noopener noreferrer" class="">Bekijk de video Beslisboom Open Standaarden →</a></p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="handig-om-bij-de-hand-te-hebben">Handig om bij de hand te hebben<a href="https://developer.overheid.nl/blog/2026/08/26/beslisboom-open-standaarden#handig-om-bij-de-hand-te-hebben" class="hash-link" aria-label="Direct link naar Handig om bij de hand te hebben" title="Direct link naar Handig om bij de hand te hebben" translate="no">​</a></h2>
<ul>
<li class=""><strong>Informatieveiligheid</strong>: veel overheidsorganisaties passen de BIO toe
(gelijkwaardig aan ISO 27001/27002). De
<a href="https://www.bio-overheid.nl/ico-wizard/" target="_blank" rel="noopener noreferrer" class="">ICO Wizard</a> van het CIP helpt je de
juiste veiligheidsnormen tijdig in beeld te krijgen, zodat ze niet achteraf in
je eisen hoeven te worden gepropt.</li>
<li class=""><strong>Voorbeelden uit de praktijk</strong>: in de
<a href="https://www.forumstandaardisatie.nl/metingen/monitor" target="_blank" rel="noopener noreferrer" class="">Monitor Open Standaarden</a>
zie je hoe andere projecten standaarden hebben toegepast. Die data is ook
ontsloten via de
<a href="https://www.noraonline.nl/wiki/Monitor_Open_Standaarden" target="_blank" rel="noopener noreferrer" class="">NORA</a>.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="van-afspraak-naar-code">Van afspraak naar code<a href="https://developer.overheid.nl/blog/2026/08/26/beslisboom-open-standaarden#van-afspraak-naar-code" class="hash-link" aria-label="Direct link naar Van afspraak naar code" title="Direct link naar Van afspraak naar code" translate="no">​</a></h2>
<p>Standaarden afspreken is één ding; ervoor zorgen dat ze nageleefd worden in je
software is een vak apart. Gebruik daarom de beslisboom om uit te vinden welke
standaarden van toepassing zijn op jouw project, en check welke tooling er
beschikbaar is voor welke standaard.</p>
<p><a href="https://www.forumstandaardisatie.nl/beslisboom/beslisboom-open-standaarden" target="_blank" rel="noopener noreferrer" class="">Direct naar de Beslisboom →</a></p>]]></content>
        <author>
            <name>Vivian van der Heijden-Hanssen</name>
        </author>
        <category label="Interoperabiliteit" term="Interoperabiliteit"/>
        <category label="Forum Standaardisatie" term="Forum Standaardisatie"/>
        <category label="Standaarden" term="Standaarden"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL onder de loep (deel 3): zes uitdagingen bij schema-ontwerp]]></title>
        <id>https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp</id>
        <link href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp"/>
        <updated>2026-08-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[De flexibiliteit van GraphQL verplaatst complexiteit van de client naar
het schema. In deel 3 van deze serie behandelen we zes uitdagingen die je
in de praktijk tegenkomt bij schema-ontwerp: paginering, het
standaardisatie-misverstand, union types, custom scalars, autorisatie en
content negotiation.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="GraphQL onder de loep" src="https://developer.overheid.nl/assets/images/graphql-onder-de-loep-e07384148936c384d21d833215dd432c.jpg" width="1731" height="909" class="img_rVHu"></p>
<p>In <a class="" href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten">deel 2</a> zagen we dat
de flexibiliteit van GraphQL een beheeropgave met zich meebrengt. In dit deel
kijken we naar de ontwerpkant. De rode draad: veel zaken die je in REST oplost
met mechanismen van HTTP (headers, statuscodes, media types, middleware op
routes) moeten in GraphQL expliciet gemodelleerd worden in het schema en de
resolvers. Dat maakt schema's en queries complexer dan de voorbeelden uit deel 1
doen vermoeden. We behandelen zes uitdagingen die je in vrijwel elk
GraphQL-project van enige omvang tegenkomt.</p>
<div class="theme-admonition theme-admonition-info admonition_jS7q alert alert--info"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>GraphQL onder de loep</div><div class="admonitionContent_ZZhP"><p>Dit artikel is deel 3 van een vierdelige serie:</p><ol>
<li class=""><a class="" href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie">Een kennismaking</a></li>
<li class=""><a class="" href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten">Flexibel bevragen, en wat dat kost</a></li>
<li class="">Zes uitdagingen bij schema-ontwerp (dit deel)</li>
<li class=""><a class="" href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader">Wanneer wel, en wanneer niet?</a></li>
</ol></div></div>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>GraphQL standaardiseert de querytaal, maar niet de conventies daarbovenop. Dat
merk je bij elk van de zes uitdagingen in dit deel:</p><ol>
<li class="">Paginering vereist al snel Cursor Connections: drie extra types per lijst.</li>
<li class="">Filtering en sortering werken in elk framework anders.</li>
<li class="">Union types leggen dispatch-werk bij de client, ook bij foutafhandeling.</li>
<li class="">Custom scalars zoals GeoJSON vergen libraries aan beide kanten.</li>
<li class="">Autorisatie verliest het route-anker: per veld, per operatie, of beide.</li>
<li class="">Meerdere responseformaten aanbieden past slecht bij het model.</li>
</ol><p>De oplossingen bouw je grotendeels zelf.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="1-paginering-laat-het-schema-groeien">1. Paginering laat het schema groeien<a href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp#1-paginering-laat-het-schema-groeien" class="hash-link" aria-label="Direct link naar 1. Paginering laat het schema groeien" title="Direct link naar 1. Paginering laat het schema groeien" translate="no">​</a></h2>
<p>Elk lijstveld heeft paginering nodig; dat leerde deel 2 al. De de-facto
standaard hiervoor is de
<a href="https://relay.dev/graphql/connections.htm" target="_blank" rel="noopener noreferrer" class="">GraphQL Cursor Connections-specificatie</a>
uit Facebooks Relay-framework, aanbevolen in de
<a href="https://graphql.org/learn/pagination/" target="_blank" rel="noopener noreferrer" class="">officiële GraphQL-documentatie</a>. Kijk
wat er met ons schema uit deel 1 gebeurt:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token comment"># Vóór: eenvoudig, maar onbegrensd</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Organisatie</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">apis</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token class-name">Api</span><span class="token operator">!</span><span class="token punctuation">]</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token comment"># Ná: Cursor Connections</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Organisatie</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">apis</span><span class="token punctuation">(</span><span class="token attr-name">first</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">Int</span><span class="token punctuation">,</span><span class="token plain"> </span><span class="token attr-name">after</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token class-name">ApiConnection</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">ApiConnection</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">edges</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token class-name">ApiEdge</span><span class="token operator">!</span><span class="token punctuation">]</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">pageInfo</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token class-name">PageInfo</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">ApiEdge</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">node</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token class-name">Api</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">cursor</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">PageInfo</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">hasNextPage</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">Boolean</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">endCursor</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Drie extra types voor één lijstveld (en dan is <code>PageInfo</code> hier nog
vereenvoudigd: de spec vereist ook <code>hasPreviousPage</code> en <code>startCursor</code>), en elke
query wordt navenant dieper:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property-query">organisatie</span><span class="token punctuation">(</span><span class="token attr-name">id</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"min-bzk"</span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token property-query">apis</span><span class="token punctuation">(</span><span class="token attr-name">first</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token number">20</span><span class="token punctuation">,</span><span class="token plain"> </span><span class="token attr-name">after</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"Y3Vyc29yOjIw"</span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token object">edges</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">        </span><span class="token object">node</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">titel</span><span class="token plain"> </span><span class="token property">versie</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token object">pageInfo</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">hasNextPage</span><span class="token plain"> </span><span class="token property">endCursor</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Ter vergelijking: in REST is hetzelfde doorgaans twee queryparameters
(<code>?page=2&amp;per_page=20</code> of een cursor) en een <code>Link</code>-header. Ook dat is geen
universeel gegeven (er bestaan page-, offset- en cursorvarianten, en profielen
zoals de ADR bestaan juist om die keuze uniform te maken), maar het verschil zit
in wáár de complexiteit landt: bij REST in parameters en headers, bij GraphQL in
de structuur van schema en query. De Connections-structuur heeft goede redenen
(stabiele cursors, metadata per resultaat), maar het patroon herhaalt zich voor
élk lijstveld, en wie totalen of facetten toevoegt, ziet de envelope verder
groeien.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="2-het-standaardisatie-misverstand">2. Het standaardisatie-misverstand<a href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp#2-het-standaardisatie-misverstand" class="hash-link" aria-label="Direct link naar 2. Het standaardisatie-misverstand" title="Direct link naar 2. Het standaardisatie-misverstand" translate="no">​</a></h2>
<p>Een hardnekkig misverstand is dat GraphQL zaken als filtering, sortering en
zoeken "standaard oplost". In werkelijkheid standaardiseert de specificatie de
<em>taal</em> (syntax, typesysteem, executie), maar vrijwel geen <em>conventies</em>
daarbovenop. De Cursor Connections-spec uit de vorige paragraaf is vrijwel de
enige breed gedragen conventie, en zelfs die is formeel geen onderdeel van de
GraphQL-specificatie.</p>
<p>Filtering en sortering zijn daardoor in elk framework anders vormgegeven.
Dezelfde vraag (actieve API's waarvan de titel "register" bevat, alfabetisch
gesorteerd) in twee populaire servers:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token comment"># Hasura</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property-query">apis</span><span class="token punctuation">(</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token attr-name">where</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">status</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">_eq</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"actief"</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token plain"> </span><span class="token attr-name">titel</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">_ilike</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"%register%"</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token attr-name">order_by</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">titel</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token property">asc</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">titel</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token comment"># HotChocolate (.NET)</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property-query">apis</span><span class="token punctuation">(</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token attr-name">where</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">status</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">eq</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"actief"</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token plain"> </span><span class="token attr-name">titel</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">contains</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"register"</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token attr-name">order</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">titel</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token constant">ASC</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">titel</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Vergelijkbare maar nét andere dialecten bestaan voor
<a href="https://www.graphile.org/postgraphile/filtering/" target="_blank" rel="noopener noreferrer" class="">PostGraphile</a>,
Prisma-gebaseerde servers en andere frameworks. Wie, zoals in deel 2 beschreven,
voor zo'n framework kiest vanwege de efficiënte vertaling naar SQL, neemt het
dialect op de koop toe: de serverkeuze werkt direct door in het publieke
contract van de API. Voor één project is dat overkomelijk, maar in een landschap
waarin API's van verschillende organisaties op elkaar moeten aansluiten, zoals
binnen de overheid, zijn kennis en tooling zo niet zonder meer overdraagbaar.
Ook in REST komen zulke conventies niet uit de standaard zelf; daarvoor bestaan
profielen als de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules">REST API Design Rules</a>.
Een vergelijkbaar afsprakenkader bestaat voor GraphQL nog niet.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="3-union-types-en-foutafhandeling">3. Union types en foutafhandeling<a href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp#3-union-types-en-foutafhandeling" class="hash-link" aria-label="Direct link naar 3. Union types en foutafhandeling" title="Direct link naar 3. Union types en foutafhandeling" translate="no">​</a></h2>
<p>Sommige velden kunnen meerdere types opleveren. Denk aan een zoekfunctie over
het register die zowel API's als organisaties vindt; in GraphQL modelleer je dat
met een <em>union</em>:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">union</span><span class="token plain"> </span><span class="token class-name">ZoekResultaat</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token property">Api</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token property">Organisatie</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Query</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">zoek</span><span class="token punctuation">(</span><span class="token attr-name">term</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token class-name">ZoekResultaat</span><span class="token operator">!</span><span class="token punctuation">]</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>De client moet vervolgens per mogelijk type een <em>inline fragment</em> schrijven en
op het metaveld <code>__typename</code> dispatchen:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property-query">zoek</span><span class="token punctuation">(</span><span class="token attr-name">term</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"adressen"</span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token property">__typename</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token operator">...</span><span class="token plain"> </span><span class="token keyword">on</span><span class="token plain"> </span><span class="token class-name">Api</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">titel</span><span class="token plain"> </span><span class="token property">versie</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token operator">...</span><span class="token plain"> </span><span class="token keyword">on</span><span class="token plain"> </span><span class="token class-name">Organisatie</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">naam</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Dat werkt, maar het dispatch-werk ligt bij de client: elke afnemer, in elke
taal, moet dit patroon implementeren. In REST blijft hetzelfde probleem
doorgaans buiten het contract: aparte endpoints per resourcetype, of een
expliciet typeveld in de response.</p>
<p>Foutafhandeling maakt het verschil het scherpst zichtbaar. GraphQL-responses
komen vrijwel altijd terug met HTTP-status <code>200 OK</code>, ook als er iets misging;
fouten staan in een aparte, generieke en ongetypeerde <code>errors</code>-lijst in de body.
Voor "niet gevonden" volstaat een nullable veld (zoals <code>organisatie</code> in deel 1),
maar voor verwachte foutsituaties die zelf informatie dragen, wordt ditzelfde
union-mechanisme ingezet: het patroon
<a href="https://www.apollographql.com/docs/graphos/schema-design/guides/errors-as-data-explained" target="_blank" rel="noopener noreferrer" class=""><em>errors as data</em></a>,
geïntroduceerd door Sasha Solomon in
<a href="https://sachee.medium.com/200-ok-error-handling-in-graphql-7ec869aec9bc" target="_blank" rel="noopener noreferrer" class="">"200 OK! Error Handling in GraphQL"</a>,
met dezelfde dispatch-plicht voor de client als gevolg. REST gebruikt hiervoor
statuscodes met een
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/architectuur/problem-details"><code>application/problem+json</code></a>-body:
gestandaardiseerd (RFC 9457) en zonder extra schemawerk.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="4-custom-scalars-coupling-aan-beide-kanten">4. Custom scalars: coupling aan beide kanten<a href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp#4-custom-scalars-coupling-aan-beide-kanten" class="hash-link" aria-label="Direct link naar 4. Custom scalars: coupling aan beide kanten" title="Direct link naar 4. Custom scalars: coupling aan beide kanten" translate="no">​</a></h2>
<p>Het typesysteem van GraphQL kent standaard vijf scalars: <code>Int</code>, <code>Float</code>,
<code>String</code>, <code>Boolean</code> en <code>ID</code>. Een datumtype ontbreekt bijvoorbeeld. Voor alles
daarbuiten definieer je <em>custom scalars</em>, en daar wringt het. Een scalar is voor
de GraphQL-runtime een black box: het schema zegt niets over de structuur, dus
serialisatie en validatie moeten aan de server- én clientkant met dezelfde
afspraken (en meestal: dezelfde library) worden geïmplementeerd. Daarmee
ontstaat coupling buiten het typesysteem om.</p>
<p>Geodata maakt het probleem goed zichtbaar. Een GeoJSON-geometrie is in
standaardtypes praktisch niet uit te drukken: coördinaten van een polygon zijn
lijsten van lijsten van lijsten, en GraphQL kent geen generieke JSON-structuren.
De praktijk is daarom vrijwel altijd een custom scalar die een JSON-blob
doorlaat:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">scalar</span><span class="token plain"> </span><span class="token class-name">GeoJSON</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token directive function">@specifiedBy</span><span class="token punctuation">(</span><span class="token attr-name">url</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"https://datatracker.ietf.org/doc/html/rfc7946"</span><span class="token punctuation">)</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Gebouw</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">id</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">ID</span><span class="token operator">!</span><span class="token plain"> </span><span class="token attr-name">geometrie</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token class-name">GeoJSON</span><span class="token operator">!</span><span class="token plain"> </span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Voor dit veld, waar structuur juist belangrijk is, valt de typering dus weg. Er
bestaan hulpmiddelen: <code>@specifiedBy</code> verwijst naar een externe specificatie, de
<a href="https://the-guild.dev/graphql/scalars" target="_blank" rel="noopener noreferrer" class="">graphql-scalars-library</a> biedt
kant-en-klare scalars (waaronder GeoJSON) en de GraphQL Foundation host een
<a href="https://scalars.graphql.org/" target="_blank" rel="noopener noreferrer" class="">register van scalar-specificaties</a>. Ze maken de
afspraak vindbaar en het werk kleiner, maar de coupling blijft: <code>@specifiedBy</code>
is een verwijzing voor ontwikkelaars en geen instructie die de runtime uitvoert,
en server en client hebben nog steeds elk een implementatie nodig die dezelfde
interpretatie volgt. Wijken server en client in library of versie van elkaar af,
dan keurt het schema de waarde alsnog goed en komt de fout pas boven bij het
interpreteren van de data.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="5-autorisatie-verliest-zijn-ankerpunt">5. Autorisatie verliest zijn ankerpunt<a href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp#5-autorisatie-verliest-zijn-ankerpunt" class="hash-link" aria-label="Direct link naar 5. Autorisatie verliest zijn ankerpunt" title="Direct link naar 5. Autorisatie verliest zijn ankerpunt" translate="no">​</a></h2>
<p>In REST valt autorisatie vaak samen met de resource en de route, bijvoorbeeld
met <a class="" href="https://developer.overheid.nl/kennisbank/security/authenticatie/oauth">OAuth 2.0</a>-scopes per endpoint.
Eén regel in een middleware of
<a class="" href="https://developer.overheid.nl/kennisbank/security/tutorials/apisix-opa-keycloak">API-gateway</a> dekt een heel
endpoint:</p>
<div class="language-text codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-text codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token plain">GET /apis/{id}           → publiek</span><br></div><div class="token-line"><span class="token plain">GET /apis/{id}/notities  → alleen rol BEHEERDER</span><br></div></code></pre></div></div>
<p>In GraphQL bestaat die route niet: elk veld is bereikbaar via willekeurig veel
paden door de graph, via <code>api(id: ...)</code>, via <code>organisatie { apis { ... } }</code> of
via een zoekresultaat. Het ankerpunt waaraan je een regel ophangt, kies je dus
zelf: het veld of de operatie.</p>
<p><strong>Per veld.</strong> Gangbaar zijn checks in resolvers en schema-directives zoals
<code>@auth</code>:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Api</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">interneNotities</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token plain"> </span><span class="token directive function">@auth</span><span class="token punctuation">(</span><span class="token attr-name">requires</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token constant">BEHEERDER</span><span class="token punctuation">)</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>De specificatie kent zo'n directive niet. Autorisatie komt in GraphQL zelf
helemaal niet voor, dus elke server en gateway kiest een eigen vorm. Wat er wel
is, is advies: de
<a href="https://graphql.org/learn/authorization/" target="_blank" rel="noopener noreferrer" class="">officiële documentatie</a> raadt aan de
logica onder de resolvers in de businesslaag te leggen, zodat de GraphQL-laag
zelf geen regels bevat die je kunt vergeten. Lastig blijft de context, want
hetzelfde veld kan per pad andere regels vragen: een e-mailadres dat de eigen
beheerder mag zien, hoort niet in een zoekresultaat. Een eigen type per context
lost dat op en laat het schema opnieuw groeien. En foutgevoelig is het: in
november 2025 publiceerde Apollo
<a href="https://github.com/apollographql/federation/security/advisories/GHSA-mx7m-j9xf-62hw" target="_blank" rel="noopener noreferrer" class="">twee security advisories</a>
waarbij de compositielogica van federated schema's field-level access control
liet omzeilen. Autorisatie per veld over een graph kent intrinsiek meer edge
cases dan per route, zeker als die graph over meerdere services is verdeeld.</p>
<p><strong>Per operatie.</strong> Wie met persisted queries werkt (deel 2), heeft weer een
eindige, benoemde set operaties en kan rechten per document toekennen,
functioneel gelijk aan scopes per endpoint. De handhaving schuift daarmee naar
voren, naar een toets vóór executie, en omdat een vast document ook het pad
vastlegt, wordt het e-mailadres uit het voorbeeld hierboven vooraf toetsbaar.
Ook hier is de vorm niet gestandaardiseerd: de persisted operations-RFC uit deel
2 is nog een voorstel.</p>
<p>Geen van beide ankers dekt de gegevens zelf. Een document <code>organisatie(id: $id)</code>
legt vast welke vorm een afnemer mag opvragen, niet welke organisaties hij mag
zien. Staat de identificatie in een variabele, dan kan een policy enforcement
point die aan een centraal policy decision point voorleggen, net als bij een
pad-parameter in REST. Komen de objecten pas uit de traversal, zoals bij een
lijst of een geneste relatie, dan valt er vóór executie niets te beoordelen. De
praktijk is dus een combinatie die je zelf ontwerpt: het grofmazige deel aan de
voordeur, het gegevensafhankelijke deel onder de resolvers.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="6-content-negotiation-past-niet-in-het-model">6. Content negotiation past niet in het model<a href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp#6-content-negotiation-past-niet-in-het-model" class="hash-link" aria-label="Direct link naar 6. Content negotiation past niet in het model" title="Direct link naar 6. Content negotiation past niet in het model" translate="no">​</a></h2>
<p>REST kent een gestandaardiseerd mechanisme om dezelfde resource in meerdere
formaten aan te bieden: content negotiation via de <code>Accept</code>-header.</p>
<div class="language-http codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-http codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token plain">GET /gebouwen/0363100012345678 HTTP/1.1</span><br></div><div class="token-line"><span class="token plain">Accept: application/geo+json</span><br></div></code></pre></div></div>
<p>Dezelfde URL kan zo plain JSON, GeoJSON, XML of bijvoorbeeld een
<a class="" href="https://developer.overheid.nl/kennisbank/security/wetgeving-en-beleid/eudi-wallet">Verifiable Credential</a>
opleveren, zonder dat het API-ontwerp verandert. GraphQL kent dit mechanisme
niet: er is één responsevorm, gedicteerd door het schema. Alternatieve
representaties moeten dus <em>in het schema zelf</em> worden gemodelleerd, als extra
velden (<code>gebouw { alsGeoJSON }</code>), aparte queries of custom scalars. Zo sijpelen
formaatdetails door in wat een representatie-onafhankelijk datamodel zou moeten
zijn, en groeit het schema met elk extra formaat. Voor API's waar meerdere
representaties een kernvereiste zijn, zoals geo-API's of API's die verifieerbare
gegevens uitgeven, is dit een serieuze beperking van het model.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-balans">De balans<a href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp#de-balans" class="hash-link" aria-label="Direct link naar De balans" title="Direct link naar De balans" translate="no">​</a></h2>
<p>Geen van deze zes uitdagingen is een showstopper, en voor elk bestaat een
werkbaar patroon. Maar samen tekenen ze een consistent beeld: GraphQL geeft je
een krachtig, generiek bevragingsmodel en vraagt in ruil daarvoor dat je
conventies die REST van HTTP en van standaarden als de ADR cadeau krijgt, zelf
ontwerpt, bouwt en bewaakt. Daarmee is de vraag niet óf GraphQL werkt (dat doet
het aantoonbaar, ook op grote schaal), maar wanneer die opgave in verhouding
staat tot wat het oplevert. Dat is het onderwerp van
<a class="" href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader">deel 4</a>, het slot van deze serie.</p>]]></content>
        <author>
            <name>Joost Farla</name>
        </author>
        <category label="API" term="API"/>
        <category label="API Design" term="API Design"/>
        <category label="GraphQL" term="GraphQL"/>
        <category label="REST API design" term="REST API design"/>
        <category label="Interoperabiliteit" term="Interoperabiliteit"/>
        <category label="Standaarden" term="Standaarden"/>
        <category label="Geodata" term="Geodata"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL onder de loep (deel 2): flexibel bevragen, en wat dat kost]]></title>
        <id>https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten</id>
        <link href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten"/>
        <updated>2026-08-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[De kernbelofte van GraphQL is flexibiliteit: de client bepaalt welke data
terugkomt en over- en underfetching verdwijnen. In deel 2 van deze serie
kijken we naar de keerzijde van die belofte, zoals onvoorspelbare
performance, een groter aanvalsoppervlak en lastige caching, en naar de
maatregelen waarmee je een GraphQL-API beheersbaar houdt.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="GraphQL onder de loep" src="https://developer.overheid.nl/assets/images/graphql-onder-de-loep-e07384148936c384d21d833215dd432c.jpg" width="1731" height="909" class="img_rVHu"></p>
<p>In het <a class="" href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie">eerste deel</a> van deze serie
maakten we kennis met GraphQL: een getypeerde querytaal waarmee de client exact
bepaalt welke data hij ontvangt. Die flexibiliteit is de belangrijkste reden om
voor GraphQL te kiezen. In dit deel zetten we eerst de voordelen op een rij en
kijken we daarna naar de keerzijde: wat betekent het voor de performance en
beschikbaarheid van je API als elke client willekeurige queries kan
samenstellen? En vooral: hoe stel je daar grenzen aan?</p>
<div class="theme-admonition theme-admonition-info admonition_jS7q alert alert--info"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>GraphQL onder de loep</div><div class="admonitionContent_ZZhP"><p>Dit artikel is deel 2 van een vierdelige serie:</p><ol>
<li class=""><a class="" href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie">Een kennismaking</a></li>
<li class="">Flexibel bevragen, en wat dat kost (dit deel)</li>
<li class=""><a class="" href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp">Zes uitdagingen bij schema-ontwerp</a></li>
<li class=""><a class="" href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader">Wanneer wel, en wanneer niet?</a></li>
</ol></div></div>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>GraphQL lost over- en underfetching structureel op en geeft clientteams
autonomie: nieuwe schermen zonder nieuwe endpoints. De prijs: de server verliest
de controle over de zwaarte van requests, en de database is niet langer te
optimaliseren voor een vaste set toegangspatronen. Maatregelen zoals depth
limiting, cost analysis en persisted queries zijn daarom basisinrichting en geen
optionele extra's, ook volgens OWASP. En caching, bij REST grotendeels door HTTP
gefaciliteerd, organiseer je in GraphQL zelf.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-voordelen">De voordelen<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#de-voordelen" class="hash-link" aria-label="Direct link naar De voordelen" title="Direct link naar De voordelen" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="exact-de-benodigde-data-in-één-roundtrip">Exact de benodigde data, in één roundtrip<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#exact-de-benodigde-data-in-%C3%A9%C3%A9n-roundtrip" class="hash-link" aria-label="Direct link naar Exact de benodigde data, in één roundtrip" title="Direct link naar Exact de benodigde data, in één roundtrip" translate="no">​</a></h3>
<p>Het voorbeeld uit deel 1 liet het al zien: waar een REST-client soms drie of
vier calls nodig heeft en per call te veel of te weinig data ontvangt, haalt een
GraphQL-client alles in één request op. Voor toepassingen met veel
schermvarianten, trage netwerken of mobiele clients is dat een reëel en meetbaar
voordeel.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="autonomie-voor-clientteams">Autonomie voor clientteams<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#autonomie-voor-clientteams" class="hash-link" aria-label="Direct link naar Autonomie voor clientteams" title="Direct link naar Autonomie voor clientteams" translate="no">​</a></h3>
<p>Minstens zo belangrijk is het organisatorische effect. In een REST-landschap kan
een nieuw scherm een backend-aanpassing vergen: een nieuw of aangepast endpoint
en afstemming over de representatie. Met GraphQL stelt het frontend-team zelf
een nieuwe query samen op het bestaande schema. Bij organisaties met veel
consumerende teams (of externe afnemers met uiteenlopende behoeften) scheelt dat
merkbaar in doorlooptijd en afstemming.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="een-sterk-getypeerd-zelfbeschrijvend-contract">Een sterk getypeerd, zelfbeschrijvend contract<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#een-sterk-getypeerd-zelfbeschrijvend-contract" class="hash-link" aria-label="Direct link naar Een sterk getypeerd, zelfbeschrijvend contract" title="Direct link naar Een sterk getypeerd, zelfbeschrijvend contract" translate="no">​</a></h3>
<p>Het schema is een machineleesbaar contract, en daarop bouwt een breed
ecosysteem: validatie van elke query tegen het schema, codegeneratie voor
clients in vrijwel elke taal, en interactieve verkenning via introspectie.</p>
<p>In het REST-ecosysteem vervult
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/openapi-specification">OpenAPI</a>
dezelfde rol, met vergelijkbare tooling, en de ADR verplichten zowel een
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules/hoe-te-voldoen/doc-openapi">OpenAPI-beschrijving</a>
als het
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules/hoe-te-voldoen/publish-openapi">publiceren daarvan op <code>/openapi.json</code></a>.
Het verschil zit in de plaats van het contract. Een OpenAPI-document is een
apart artefact naast de implementatie: of je het met de hand onderhoudt, uit
code genereert of als bron voor codegeneratie gebruikt, synchroon houden blijft
een expliciete inspanning. In GraphQL is het schema de runtime zelf. De server
weigert elke query die er niet op past en geeft via introspectie precies het
schema terug dat hij uitvoert, dus op typeniveau kan het contract niet uit de
pas lopen.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="evolueren-zonder-versies">Evolueren zonder versies<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#evolueren-zonder-versies" class="hash-link" aria-label="Direct link naar Evolueren zonder versies" title="Direct link naar Evolueren zonder versies" translate="no">​</a></h3>
<p>REST-API's krijgen bij breaking changes doorgaans een
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules/hoe-te-voldoen/semver">nieuwe major versie</a>.
In GraphQL is dat ongebruikelijk: velden worden gemarkeerd met <code>@deprecated</code> en
blijven bestaan zolang er clients zijn die ze gebruiken:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Api</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">titel</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">documentatieUrl</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token plain"> </span><span class="token directive function">@deprecated</span><span class="token punctuation">(</span><span class="token attr-name">reason</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"Gebruik `specificatieUrl`."</span><span class="token punctuation">)</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">specificatieUrl</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Ook OpenAPI kent <code>deprecated</code>: voor operaties en parameters, en via het Schema
Object ook voor afzonderlijke velden. Het verschil zit in de feedback. Een
REST-response bevat doorgaans de volledige representatie, dus de aanbieder ziet
niet of een afnemer een verouderd veld werkelijk gebruikt; uitfaseren gebeurt op
basis van aankondigingen en aannames, tenzij de API met sparse fieldsets werkt.
Omdat elke GraphQL-client expliciet benoemt welke velden hij opvraagt, is per
veld en per afnemer meetbaar wat nog in gebruik is. Dat maakt gerichte
uitfasering mogelijk in plaats van een "big bang"-migratie.</p>
<p>Wat overblijft is vooral een verschil in gewoonte: bij REST draait een nieuwe
major versie een tijd naast de oude, bij GraphQL groeit één schema additief mee,
omdat een tweede versie de hele graph zou dupliceren. Gratis is dat niet, want
het schema draagt zijn verleden mee, en definitief verwijderen blijft in beide
modellen een breaking change.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-keerzijde-de-server-verliest-voorspelbaarheid">De keerzijde: de server verliest voorspelbaarheid<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#de-keerzijde-de-server-verliest-voorspelbaarheid" class="hash-link" aria-label="Direct link naar De keerzijde: de server verliest voorspelbaarheid" title="Direct link naar De keerzijde: de server verliest voorspelbaarheid" translate="no">​</a></h2>
<p>Bij een REST-API kent de aanbieder elk endpoint en kan die per endpoint
redeneren over de kosten: welke database-queries, hoeveel data, welke
cache-strategie. Bij GraphQL bestaat "het endpoint" niet meer: elke client stelt
zijn eigen bevraging samen. De consequentie: de zwaarte van een request wordt
bepaald door de client, niet door de aanbieder.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="het-n1-probleem">Het N+1-probleem<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#het-n1-probleem" class="hash-link" aria-label="Direct link naar Het N+1-probleem" title="Direct link naar Het N+1-probleem" translate="no">​</a></h3>
<p>Resolvers werken per veld. Een naïeve implementatie van ons voorbeeldschema:</p>
<div class="language-js codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-js codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">const</span><span class="token plain"> resolvers </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token literal-property property">Query</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token function-variable function">organisaties</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token arrow operator">=&gt;</span><span class="token plain"> db</span><span class="token punctuation">.</span><span class="token property-access">organisaties</span><span class="token punctuation">.</span><span class="token method function property-access">findAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token literal-property property">Organisatie</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token comment">// wordt aangeroepen voor élke organisatie in het resultaat</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token function-variable function">apis</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation">(</span><span class="token parameter">organisatie</span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token arrow operator">=&gt;</span><span class="token plain"> db</span><span class="token punctuation">.</span><span class="token property-access">apis</span><span class="token punctuation">.</span><span class="token method function property-access">findByOrganisatie</span><span class="token punctuation">(</span><span class="token plain">organisatie</span><span class="token punctuation">.</span><span class="token property-access">id</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><span class="token punctuation">;</span><br></div></code></pre></div></div>
<p>Een query naar 100 organisaties met hun API's leidt zo tot 1 + 100
database-queries. Hetzelfde patroon geldt voor autorisatie: een toegangscheck
die per object wordt uitgevoerd, herhaalt zich in diezelfde query net zo
makkelijk honderd keer. Dit <em>N+1-probleem</em> is beheersbaar, bijvoorbeeld met
batching via een <a href="https://github.com/graphql/dataloader" target="_blank" rel="noopener noreferrer" class="">DataLoader</a>, maar het
lost zichzelf niet op en is, zoals hieronder blijkt, ook niet gratis. Zonder
maatregelen blijft het vaak onopgemerkt tot er productielast op staat.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="een-database-die-zijn-bevragingen-niet-kent">Een database die zijn bevragingen niet kent<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#een-database-die-zijn-bevragingen-niet-kent" class="hash-link" aria-label="Direct link naar Een database die zijn bevragingen niet kent" title="Direct link naar Een database die zijn bevragingen niet kent" translate="no">​</a></h3>
<p>Achter het N+1-probleem gaat een structureler vraagstuk schuil. Bij een REST-API
is het aantal toegangspatronen eindig: per endpoint schrijf of genereer je de
bijbehorende database-queries, ontwerp je de juiste indexen en kun je desnoods
een toegesneden read model inrichten. De database wordt, kortom, geoptimaliseerd
voor bekende bevragingen.</p>
<p>Bij GraphQL is de bevragingsruimte open. Elke nieuwe query die een clientteam
samenstelt, kan een pad door de graph volgen waarvoor geen index of
geoptimaliseerde query bestaat; de autonomie die hierboven een voordeel was, is
hier de bron van onvoorspelbaarheid. Optimalisatie wordt daarmee reactief in
plaats van proactief: je monitort welke operaties traag zijn en bouwt achteraf
indexen bij, telkens opnieuw wanneer clients hun queries wijzigen. Ook
capaciteitsplanning wordt lastiger, omdat de databasebelasting kan verschuiven
met elke client-release, zonder dat er aan de API zelf iets verandert.</p>
<p>Batching via een DataLoader verzacht dit maar gedeeltelijk. Het voorkomt dubbele
en herhaalde fetches, maar levert per nestingniveau een aparte
<code>WHERE id IN (...)</code>-query op, geen join; de queryplanner van de database kan dus
niet doen waar hij goed in is. Frameworks als Hasura en PostGraphile kiezen
daarom een andere route en vertalen een GraphQL-query naar één SQL-statement.
Dat is efficiënt, maar koppelt het schema aan het framework en vaak ook aan de
databasestructuur; op die vorm van coupling komen we in deel 3 terug.</p>
<p>Daar stapelen zich kleinere ongemakken bovenop: efficiënte cursor-paginering
vereist passende indexen, en een veld als <code>totalCount</code> kan per opgevraagde
pagina een dure count-query betekenen. En ook hier bieden de maatregelen die
verderop aan bod komen verlichting: wie kiest voor persisted queries, maakt de
set bevragingen weer eindig, en daarmee gericht te optimaliseren.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="geneste-queries-en-het-aanvalsoppervlak">Geneste queries en het aanvalsoppervlak<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#geneste-queries-en-het-aanvalsoppervlak" class="hash-link" aria-label="Direct link naar Geneste queries en het aanvalsoppervlak" title="Direct link naar Geneste queries en het aanvalsoppervlak" translate="no">​</a></h3>
<p>Omdat ons schema circulaire relaties bevat (een organisatie heeft API's, een API
heeft een organisatie), is dit een geldige query:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token object">apis</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token object">organisatie</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token object">apis</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">        </span><span class="token object">organisatie</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">          </span><span class="token object">apis</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">            </span><span class="token object">organisatie</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">              </span><span class="token object">apis</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">titel</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">            </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">          </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">        </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Elke extra nesting vermenigvuldigt het aantal op te halen records. Een paar
regels querytekst kan zo miljoenen databaserijen raken. Wat voor een legitieme
client een vergissing is, is voor een kwaadwillende een goedkope
denial-of-service-aanval: de
<a href="https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html" target="_blank" rel="noopener noreferrer" class="">OWASP GraphQL Cheat Sheet</a>
noemt dit als een van de grootste risico's van GraphQL-API's.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="limieten-stellen">Limieten stellen<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#limieten-stellen" class="hash-link" aria-label="Direct link naar Limieten stellen" title="Direct link naar Limieten stellen" translate="no">​</a></h2>
<p>Dit terrein is inmiddels volwassen. De gangbare maatregelen, grofweg oplopend in
geavanceerdheid:</p>
<p><strong>Depth en amount limiting.</strong> Begrens de maximale nesting depth van queries en
het maximale aantal op te vragen items per lijst. Eenvoudig te implementeren
(vrijwel elke GraphQL-server ondersteunt validatieregels) en een effectieve
eerste verdedigingslinie, hier met de library <code>graphql-depth-limit</code>:</p>
<div class="language-js codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-js codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">const</span><span class="token plain"> server </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword">new</span><span class="token plain"> </span><span class="token class-name">ApolloServer</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  schema</span><span class="token punctuation">,</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token literal-property property">validationRules</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token function">depthLimit</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br></div></code></pre></div></div>
<p><strong>Verplichte paginering.</strong> Sta geen onbegrensde lijsten toe: geef elk lijstveld
een verplicht <code>first</code>-argument met een maximum. Hoe je paginering in het schema
modelleert, komt in deel 3 uitgebreid aan bod.</p>
<p><strong>Query cost analysis.</strong> Ken elk veld een gewicht toe en bereken vóór uitvoering
de totale kosten van een query; boven een drempel wordt de query geweigerd. IBM
ontwikkelde hiervoor een
<a href="https://ibm.github.io/graphql-specs/cost-spec.html" target="_blank" rel="noopener noreferrer" class="">draft-specificatie met <code>@cost</code>- en <code>@listSize</code>-directives</a>,
waarop onder andere
<a href="https://www.apollographql.com/docs/graphos/routing/security/demand-control" target="_blank" rel="noopener noreferrer" class="">Apollo's Demand Control</a>
voortbouwt:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Query</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">apis</span><span class="token punctuation">(</span><span class="token attr-name">first</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">Int</span><span class="token operator">!</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token class-name">Api</span><span class="token operator">!</span><span class="token punctuation">]</span><span class="token operator">!</span><span class="token plain"> </span><span class="token directive function">@listSize</span><span class="token punctuation">(</span><span class="token attr-name">slicingArguments</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token string">"first"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Api</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">gerelateerdeApis</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token class-name">Api</span><span class="token operator">!</span><span class="token punctuation">]</span><span class="token operator">!</span><span class="token plain"> </span><span class="token directive function">@cost</span><span class="token punctuation">(</span><span class="token attr-name">weight</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"5"</span><span class="token punctuation">)</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p><strong>Rate limiting op kosten in plaats van op requests.</strong> Eén GraphQL-request kan
het werk van honderd REST-requests doen; een klassieke limiet op "requests per
minuut" zegt dus weinig. Ook REST-requests verschillen onderling sterk in
kosten; GraphQL maakt dat alleen eerder en explicieter zichtbaar.
<a href="https://shopify.engineering/rate-limiting-graphql-apis-calculating-query-complexity" target="_blank" rel="noopener noreferrer" class="">Shopify beschrijft in detail</a>
hoe het afnemers een kostenbudget per tijdseenheid geeft, berekend uit de
complexiteit van hun queries; GitHub hanteert een
<a href="https://docs.github.com/en/graphql/overview/rate-limits-and-node-limits-for-the-graphql-api" target="_blank" rel="noopener noreferrer" class="">vergelijkbaar puntensysteem</a>
voor zijn GraphQL-API.</p>
<p><strong>Persisted queries / trusted documents.</strong> De meest vergaande maatregel: sta
alleen queries toe die vooraf zijn geregistreerd. Clients sturen niet langer
querytekst mee, maar een identifier van een bekend, goedgekeurd document,
bijvoorbeeld een SHA-256-hash (de benoemde operaties uit deel 1 lenen zich daar
precies voor):</p>
<div class="language-json codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-json codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property">"documentId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string">"8e2f9b41…"</span><span class="token punctuation">,</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property">"variables"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">"id"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string">"min-bzk"</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Er loopt een
<a href="https://github.com/graphql/graphql-over-http/blob/main/rfcs/PersistedOperations.md" target="_blank" rel="noopener noreferrer" class="">RFC om dit te standaardiseren</a>
als onderdeel van de GraphQL over HTTP-specificatie. De observatie die daarbij
hoort: wie alleen nog vooraf geregistreerde queries toestaat, heeft de facto
weer een eindige set endpoints gecreëerd. Dat is een relativering van de
flexibiliteitsbelofte, al blijft het voordeel bestaan dat clientteams die
"endpoints" zelf definiëren zonder backend-wijziging.</p>
<p><strong>Operationele basishygiëne.</strong> Timeouts op queryniveau, limieten op
request-batching, en introspectie uitschakelen (of afschermen) in productie voor
API's die niet publiek bedoeld zijn: allemaal terug te vinden in de
eerdergenoemde OWASP Cheat Sheet.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="caching-wat-http-aan-rest-meegeeft">Caching: wat HTTP aan REST meegeeft<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#caching-wat-http-aan-rest-meegeeft" class="hash-link" aria-label="Direct link naar Caching: wat HTTP aan REST meegeeft" title="Direct link naar Caching: wat HTTP aan REST meegeeft" translate="no">​</a></h2>
<p>Er is nog een tweede keerzijde, en die is minder direct zichtbaar. Een REST-API
kan voor caching grotendeels leunen op het web zelf: elke resource heeft een
unieke URL, <code>GET</code>-responses zijn met standaard HTTP-headers (<code>Cache-Control</code>,
<code>ETag</code>) cachebaar, en elke CDN, proxy of browser kan daarmee overweg, mits de
aanbieder die headers correct zet.</p>
<p>GraphQL-verkeer loopt daarentegen vrijwel altijd als <code>POST</code> naar één endpoint.
Voor een cache is elk request daarmee uniek en oncachebaar; de
<a href="https://graphql.org/learn/caching/" target="_blank" rel="noopener noreferrer" class="">documentatie van graphql.org</a> beschrijft
dat het URL-mechanisme waarop HTTP-caching leunt, in GraphQL ontbreekt. De
gangbare mitigaties:</p>
<ul>
<li class=""><code>GET</code> gebruiken voor query-operaties, met de query in de URL (begrensd door
URL-lengtelimieten);</li>
<li class="">persisted queries combineren met <code>GET</code>: een korte hash in de URL maakt
responses wél CDN-cachebaar;</li>
<li class="">caching verplaatsen naar de client (normalized caches zoals die van Apollo
Client of Relay) of naar de server (per-veld caching in resolvers).</li>
</ul>
<p>Waar caching bij REST een eigenschap van het platform is, is het bij GraphQL een
bouwopgave. Voor API's die leunen op CDN-caching, zoals veelbevraagde
open-data-API's, weegt dit verschil zwaar.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-balans">De balans<a href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten#de-balans" class="hash-link" aria-label="Direct link naar De balans" title="Direct link naar De balans" translate="no">​</a></h2>
<p>De flexibiliteit van GraphQL is geen gratis eigenschap, maar een verschuiving
van verantwoordelijkheid: van design-time (de aanbieder ontwerpt endpoints) naar
runtime (de aanbieder bewaakt wat clients samenstellen). Wie GraphQL serieus
inzet, plant depth limiting, cost analysis, monitoring per operatie en een
cachingstrategie daarom in als onderdeel van de basisinrichting, niet als
optimalisatie achteraf.</p>
<p>In <a class="" href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp">deel 3</a> verleggen we de blik van
runtime naar design-time: wat komt er kijken bij het ontwerpen van een goed
GraphQL-schema, en waarom blijkt dat in de praktijk lastiger dan de voorbeelden
doen vermoeden?</p>]]></content>
        <author>
            <name>Joost Farla</name>
        </author>
        <category label="API" term="API"/>
        <category label="API Design" term="API Design"/>
        <category label="GraphQL" term="GraphQL"/>
        <category label="REST API design" term="REST API design"/>
        <category label="Informatiebeveiliging" term="Informatiebeveiliging"/>
        <category label="Security by Design" term="Security by Design"/>
        <category label="OWASP" term="OWASP"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Spectral onder vuur: waar wij staan]]></title>
        <id>https://developer.overheid.nl/blog/2026/07/31/spectral-onder-vuur</id>
        <link href="https://developer.overheid.nl/blog/2026/07/31/spectral-onder-vuur"/>
        <updated>2026-07-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Spectral ligt onder vuur na jaren achterstallig onderhoud en een supply chain-incident in een dependency. Waarom we niet halsoverkop overstappen, en wat we wel doen.]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="Spectral onder vuur" src="https://developer.overheid.nl/assets/images/spectral-onder-vuur-29464d8b84a56232731e45100ada16e3.png" width="1200" height="630" class="img_rVHu"></p>
<p>Spectral is een open source linter waarmee je regels voor API-documentatie
vastlegt in een ruleset en die vervolgens automatisch controleert. Die tool ligt
onder vuur. Er staan honderden issues en pull requests open, de VS Code-plugin
loopt achter, en half juli kwam daar een supply chain-incident in een van de
dependencies bovenop. Dat laatste was voor veel mensen de druppel. Omdat onze
eigen tooling op Spectral draait en de API Design Rules ermee beschreven zijn,
uitten veel mensen daar terecht hun zorgen over. Ons antwoord: we slopen
Spectral er niet halsoverkop uit, want er zit juist beweging in de richting die
we toch al op wilden. Hieronder leggen we uit waar we staan en wat we doen.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><ul>
<li class="">Onlangs vond er een security-incident plaats rondom Spectral, doordat er via
een dependency kwaadaardige code werd meegeleverd. Dit is inmiddels opgelost,
maar het is niet het enige probleem: Spectral kampt al langer met
achterstallig onderhoud.</li>
<li class="">Het rulesetformaat wordt afgesplitst van de linter en krijgt een ander
onderkomen. Daar haken wij op aan: we dragen bij aan het
<a href="https://github.com/orgs/api-commons/discussions/28" target="_blank" rel="noopener noreferrer" class="">nieuwe project</a> en denken
mee over waar dit formaat als standaard thuishoort.</li>
<li class="">We zien nog geen reden om over te stappen naar
<a href="https://quobix.com/vacuum/" target="_blank" rel="noopener noreferrer" class="">vacuum</a>: omdat we Spectral bewust en niet
automatisch updaten zijn de risico's klein, en we willen eerst deze nieuwe
route verkennen. We slopen Spectral er dus niet halsoverkop uit.</li>
<li class="">Werk je met de API Design Rules? Gebruik de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/tools/api-design-rules-linter">ADR Checker</a> in
plaats van Spectral rechtstreeks.</li>
</ul></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="wat-er-is-gebeurd">Wat er is gebeurd<a href="https://developer.overheid.nl/blog/2026/07/31/spectral-onder-vuur#wat-er-is-gebeurd" class="hash-link" aria-label="Direct link naar Wat er is gebeurd" title="Direct link naar Wat er is gebeurd" translate="no">​</a></h2>
<p>Op 14 juli werden twee kwaadaardige versies van <code>@asyncapi/specs</code> naar npm
gepubliceerd, via een gecompromitteerde branch in de repository van AsyncAPI. De
<code>latest</code>-tag wees korte tijd naar de besmette versie. De payload startte bij het
inladen van de package een achtergrondproces dat een remote access tool
downloadde, die vervolgens onder meer opgeslagen browserwachtwoorden, SSH-keys,
<code>GITHUB_TOKEN</code>, <code>NPM_TOKEN</code> en AWS-credentials wegsluisde. De details staan in
<a href="https://github.com/asyncapi/spec-json-schemas/issues/656" target="_blank" rel="noopener noreferrer" class="">issue 656 van asyncapi/spec-json-schemas</a>.</p>
<p>Waarom dat ons raakt: <code>@stoplight/spectral-rulesets</code> heeft <code>@asyncapi/specs</code> als
dependency, met een caret-range. Wie in dat tijdvenster een schone install deed
van Spectral, haalde de besmette versie binnen. Onze eigen tooling gebruikt
Spectral onder de motorkap en de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules">API Design Rules</a>
zijn met een Spectral ruleset beschreven.</p>
<p>Eerst het goede nieuws. De aanval was niet gericht op Spectral en Stoplight is
hier net zo goed slachtoffer als iedereen verderop in de keten. De kwaadaardige
versies werden snel door npm en Github verwijderd waardoor <code>latest</code> weer naar de
laatste schone versie verwees. Een verse install van vandaag is veilig.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-druppel-niet-het-begin">De druppel, niet het begin<a href="https://developer.overheid.nl/blog/2026/07/31/spectral-onder-vuur#de-druppel-niet-het-begin" class="hash-link" aria-label="Direct link naar De druppel, niet het begin" title="Direct link naar De druppel, niet het begin" translate="no">​</a></h2>
<p>Het incident zelf is dus opgelost. De reactie erop niet. Op de
Spectral-repository is op 14 juli een issue geopend met de melding dat Spectral
gecompromitteerde dependencies binnenhaalde, en dat issue staat er twee weken
later nog steeds, onbeantwoord, terwijl er in de tussentijd wel een release is
gedaan. Bij een supply chain-incident is de snelheid waarmee een maintainer
reageert belangrijker dan de vraag of het incident zijn schuld was.</p>
<p>Dat past in een beeld dat al langer zichtbaar is. Kin Lane, die al jaren als de
<em>API Evangelist</em> over dit vakgebied schrijft, onderbouwt het met cijfers in
<a href="https://apievangelist.com/2026/07/29/i-am-forking-spectral/" target="_blank" rel="noopener noreferrer" class="">de blogpost waarin hij bekendmaakt dat hij Spectral heeft geforkt</a>:
241 openstaande issues, een terugval van 93 procent in het aantal gesloten
issues ten opzichte van de piek in 2021, en een oudste openstaande pull request
van vijf jaar geleden. Daar komt bij dat de VS Code-plugin al ruim een jaar niet
is bijgewerkt, en dat er install-time telemetrie in zit die weliswaar netjes
gedocumenteerd is en uit te zetten, maar die je in een overheids-CI liever
bewust dan per ongeluk aan hebt staan.</p>
<p>Wij lopen daar zelf ook tegenaan. Een goed voorbeeld is de <code>or</code>-functie in de
ADR-ruleset,
<a href="https://github.com/developer-overheid-nl/don-site/issues/526" target="_blank" rel="noopener noreferrer" class="">waarover in november een vraag binnenkwam</a>.
Die ruleset gebruikt <code>function: or</code>, en dat is een ingebouwde functie die in
april 2025 aan Spectral is toegevoegd. De CLI kent hem en doet netjes wat er
staat. De VS Code-plugin draait op een Spectral-build van daarvoor en meldt dat
de functie niet bestaat. Dezelfde ruleset, dezelfde API, twee verschillende
uitkomsten. De melder was een paar uur kwijt aan het zoeken naar een fout die
niet in zijn API zat en ook niet in de ADR.</p>
<p>Het probleem is dus niet de regel. Het probleem is dat nergens is vastgelegd
welke functies bij welke versie van het rulesetformaat horen. Het formaat heeft
geen eigen versienummer: het is in de praktijk "wat de linter die je toevallig
draait accepteert". Voor één tool valt daarmee te leven. Voor een standaard op
de pas-toe-of-leg-uit-lijst, die door tientallen organisaties in verschillende
omgevingen wordt gedraaid, niet.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="er-zit-beweging-in">Er zit beweging in<a href="https://developer.overheid.nl/blog/2026/07/31/spectral-onder-vuur#er-zit-beweging-in" class="hash-link" aria-label="Direct link naar Er zit beweging in" title="Direct link naar Er zit beweging in" translate="no">​</a></h2>
<p>Dit is niet nieuw voor ons en we zijn er ook niet gisteren pas over gaan
nadenken. We hebben hier de afgelopen tijd meerdere gesprekken over gevoerd met
Kin en anderen in het veld, en wisten dus al dat er beweging aan zat te komen.
Wat er nu gebeurt maakt vooral zichtbaar wat er al langer speelde.</p>
<p>De kern van het betoog: Spectral is eigenlijk twee dingen in één. Het is een
specificatie voor hoe je regels over JSON- en YAML-documenten uitdrukt, en het
is een tool die die regels evalueert. Die twee zijn nooit gescheiden. Het
regelformaat leeft in de broncode van de linter en wordt mee geversioneerd met
die tool. Als de tool stilvalt, valt het formaat ook stil. En je regels zijn het
duurzame deel, niet de linter die ze toevallig uitvoert.</p>
<p>Kin's fork onder API Commons splitst die twee alsnog, in twee repositories:</p>
<ul>
<li class=""><a href="https://github.com/api-commons/spotlight-spec" target="_blank" rel="noopener noreferrer" class="">Het rulesetformaat</a> als
zelfstandige specificatie, met één portable JSON Schema (draft 2020-12) in
plaats van vijf interne draft-07 meta-schema's die aan de runtime van de
linter hangen.</li>
<li class=""><a href="https://github.com/api-commons/spotlight-tools" target="_blank" rel="noopener noreferrer" class="">De linter zelf</a> als
onderhouden build van v6.16.2, met volledige commithistorie, zonder
telemetrie, en met issues die openstaan voor reactie.</li>
</ul>
<p>Hoe een en ander uiteindelijk gaat heten staat nog open, dus verwacht daar de
komende tijd nog wijzigingen.</p>
<p>Het formaat blijft gelijk en bestaande rulesets blijven werken. Het verschil zit
in het onderhoud: verbeteringen die nu blijven liggen kunnen er wel worden
opgepakt en uitgebracht. Precies daar liep het bij <code>or</code> op vast.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="waarom-niet-gewoon-vacuum">Waarom niet gewoon vacuum?<a href="https://developer.overheid.nl/blog/2026/07/31/spectral-onder-vuur#waarom-niet-gewoon-vacuum" class="hash-link" aria-label="Direct link naar Waarom niet gewoon vacuum?" title="Direct link naar Waarom niet gewoon vacuum?" translate="no">​</a></h2>
<p>De meest gestelde vervolgvraag was waarom we niet overstappen op
<a href="https://quobix.com/vacuum/" target="_blank" rel="noopener noreferrer" class="">vacuum</a>. Dat is een goede tool en op dit moment
beter onderhouden dan Spectral. Toch is het voor ons op dit moment nog geen
vervanging, om drie redenen:</p>
<ul>
<li class="">
<p>Ten eerste is de compatibiliteit met het Spectral-rulesetformaat niet
volledig. Dat formaat is precies wat wij willen behouden: de ADR zijn ermee
beschreven, en dat geldt ook voor de rulesets die we voor OAS-,
publiccode.yml- en JSON-FG-validatie hebben geschreven.</p>
</li>
<li class="">
<p>Ten tweede is vacuum, hoe goed ook, in de praktijk een eenmansproject. Dan
verplaatsen we het probleem alleen maar: we stappen weg bij een tool waar te
weinig mensen naar omkijken, en komen uit bij een tool die van één persoon
afhangt.</p>
</li>
<li class="">
<p>Ten derde is vacuum geschreven in Go. Onze tooling moet ook in de browser en
in editors kunnen draaien, en dat wordt met een gecompileerde binary al snel
ingewikkeld. Een JavaScript-engine heeft dus onze sterke voorkeur. Dat
Spectral trager is dan vacuum weegt daar niet tegenop: de codebase van
Spectral is jarenlang organisch gegroeid en er valt nog genoeg aan te
sleutelen voordat de taal de beperkende factor wordt.</p>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="wat-we-gaan-doen">Wat we gaan doen<a href="https://developer.overheid.nl/blog/2026/07/31/spectral-onder-vuur#wat-we-gaan-doen" class="hash-link" aria-label="Direct link naar Wat we gaan doen" title="Direct link naar Wat we gaan doen" translate="no">​</a></h2>
<p><strong>Spectral blijft voorlopig in gebruik.</strong> We updaten versies in onze tooling
niet zomaar en niet automatisch. Een update is bij ons een bewuste keuze, geen
bijproduct van een build. Dat lost het onderliggende onderhoudsprobleem niet op,
maar het haalt de acute onzekerheid eruit: een linter die je in CI draait op een
versie die je zelf hebt vastgesteld, tegen specificaties die je zelf beheert, is
een beheersbaar risico. Dit incident had iedereen kunnen raken die zijn
afhankelijkheden automatisch laat meebewegen, dus het is sowieso een goed moment
om te kijken hoe dat bij jou geregeld is.</p>
<p><strong>We gaan bijdragen aan het nieuwe project.</strong> Het probleem dat Kin beschrijft,
hebben we samen met hem doorgenomen. Dat is ook precies waarom we het niet bij
toekijken laten: we helpen mee waar we kunnen, aan zowel de specificatie als de
linter. En we nodigen iedereen die met dit formaat werkt uit om hetzelfde te
doen. Hoe meer partijen meedoen, hoe minder dit afhangt van de goede wil van één
leverancier of één persoon.</p>
<p><strong>We helpen zoeken naar een plek om te landen.</strong> Een fork is nog geen standaard.
De OpenAPI Initiative is een optie, al gaat Spectral verder dan OpenAPI alleen
en sluiten de statuten van de OAI tooling expliciet uit, wat lastig is als het
er juist om gaat de specificatie en de tool bij elkaar te houden. De Linux
Foundation is een optie. En een Europese publieke-sectorplek is dat ook: een
aanzienlijk deel van de meest geavanceerde toepassing van dit formaat zit bij
Europese overheidsprogramma's, en verschillende van die landen voeren nu
hetzelfde gesprek. Wij denken daarin mee.</p>
<p>Waar wij geen voorstander van zijn, is Spectral er halsoverkop uitslopen. Dat
zou betekenen dat de ADR herschreven moet worden in een formaat dat we niet in
de hand hebben, op basis van een incident dat inmiddels is ogelost, terwijl er
juist beweging zit in de richting die wij toejuichen.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="wat-je-zelf-kunt-doen">Wat je zelf kunt doen<a href="https://developer.overheid.nl/blog/2026/07/31/spectral-onder-vuur#wat-je-zelf-kunt-doen" class="hash-link" aria-label="Direct link naar Wat je zelf kunt doen" title="Direct link naar Wat je zelf kunt doen" translate="no">​</a></h2>
<p>Werk je met de ADR, gebruik dan de
<a href="https://github.com/developer-overheid-nl/don-checker" target="_blank" rel="noopener noreferrer" class="">DON Checker</a> in plaats
van Spectral rechtstreeks. Hoe je hem draait voor ADR staat beschreven op de
pagina over de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/tools/api-design-rules-linter">ADR Checker</a> in
onze kennisbank. Deze tool draait via CLI of in de browser, en wij houden de
onderliggende linter en de rulesets bij. Je verplaatst je afhankelijkheid
daarmee naar een Nederlandse overheidsorganisatie, waarvan je mag verwachten dat
we open zijn en blijven. Mis je een regel, klopt er iets niet of loop je ergens
tegenaan, meld het dan gerust in de issues van die repository.</p>
<p>Gebruik je zelf het Spectral-rulesetformaat, laat dat dan even weten in
<a href="https://github.com/orgs/api-commons/discussions/28" target="_blank" rel="noopener noreferrer" class="">de discussion bij API Commons</a>.
Het maakt zichtbaar wie er meekijkt, en dat is precies wat er tot nu toe ontbrak
in elk gesprek over waar dit formaat thuishoort.</p>
<p>Heb je vragen over wat dit betekent voor je eigen implementatie van de ADR of
voor je gebruik van onze validatietooling, neem dan contact op via
<a href="mailto:developer.overheid@geonovum.nl" target="_blank" rel="noopener noreferrer" class="">developer.overheid@geonovum.nl</a>.</p>]]></content>
        <author>
            <name>Dimitri van Hees</name>
        </author>
        <author>
            <name>Joost Farla</name>
        </author>
        <category label="API Design Rules" term="API Design Rules"/>
        <category label="OpenAPI Specification" term="OpenAPI Specification"/>
        <category label="npm" term="npm"/>
        <category label="Informatiebeveiliging" term="Informatiebeveiliging"/>
        <category label="Open Source" term="Open Source"/>
        <category label="Standaarden" term="Standaarden"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[GraphQL onder de loep (deel 1): een kennismaking]]></title>
        <id>https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie</id>
        <link href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie"/>
        <updated>2026-07-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[GraphQL komt regelmatig voorbij in gesprekken over API's binnen de
overheid, maar wat is het eigenlijk precies? In het eerste deel van deze
vierdelige serie maken we kennis met de bouwstenen van GraphQL en laten we
zien waarom het geen "betere REST" is, maar een fundamenteel ander model
voor het ontsluiten van data.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="GraphQL onder de loep" src="https://developer.overheid.nl/assets/images/graphql-onder-de-loep-e07384148936c384d21d833215dd432c.jpg" width="1731" height="909" class="img_rVHu"></p>
<p>In gesprekken over API's binnen de overheid komt GraphQL regelmatig voorbij.
Sommige organisaties experimenteren ermee, grote internationale platformen zoals
GitHub en Shopify bieden er publieke API's mee aan, en tegelijkertijd is het
binnen de Nederlandse overheid nog nauwelijks zichtbaar: het
<a class="" href="https://developer.overheid.nl/blog/2025/06/18/het-nieuwe-api-register">API-register</a> op deze site is bewust
REST-only, en de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules">REST API Design Rules</a>
(ADR) zijn, de naam zegt het al, geschreven voor REST.</p>
<p>Reden genoeg om GraphQL eens grondig onder de loep te nemen. In een serie van
vier blogposts verkennen we wat GraphQL is, wat het oplost, welke uitdagingen
het met zich meebrengt en, als kernvraag, wanneer je het wel en wanneer je het
beter niet kunt gebruiken.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>GraphQL is een getypeerde querytaal en runtime voor API's: de client beschrijft
exact welke data hij nodig heeft en krijgt precies dat terug, via één endpoint.
Dat is een fundamenteel ander model dan REST, dat draait om resources en de
semantiek van HTTP. Dit paradigmaverschil verklaart zowel de voordelen als de
uitdagingen van GraphQL.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="wat-is-graphql">Wat is GraphQL?<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#wat-is-graphql" class="hash-link" aria-label="Direct link naar Wat is GraphQL?" title="Direct link naar Wat is GraphQL?" translate="no">​</a></h2>
<p><a href="https://graphql.org/" target="_blank" rel="noopener noreferrer" class="">GraphQL</a> is een querytaal voor API's, gecombineerd met
een schemataal om een sterk getypeerd datamodel te beschrijven en een runtime
die queries tegen dat model uitvoert. Het is in 2012 ontwikkeld bij Facebook,
dat worstelde met de datavoorziening van zijn mobiele apps, en in 2015 open
source gemaakt. Sinds eind 2018 wordt de specificatie beheerd door de
onafhankelijke <a href="https://graphql.org/foundation/" target="_blank" rel="noopener noreferrer" class="">GraphQL Foundation</a>, onderdeel
van de Linux Foundation. In september 2025 verscheen de
<a href="https://graphql.org/blog/2025-09-08-september-edition/" target="_blank" rel="noopener noreferrer" class="">September 2025 Edition</a>,
de eerste nieuwe editie sinds oktober 2021.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-bouwstenen">De bouwstenen<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#de-bouwstenen" class="hash-link" aria-label="Direct link naar De bouwstenen" title="Direct link naar De bouwstenen" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="het-schema">Het schema<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#het-schema" class="hash-link" aria-label="Direct link naar Het schema" title="Direct link naar Het schema" translate="no">​</a></h3>
<p>Het hart van elke GraphQL-API is het schema, geschreven in de Schema Definition
Language (SDL). Het schema beschrijft welke types er bestaan, hoe ze samenhangen
en welke queries mogelijk zijn. Een sterk vereenvoudigd voorbeeld, losjes
gebaseerd op het API-register:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Organisatie</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">id</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">ID</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">naam</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">apis</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token class-name">Api</span><span class="token operator">!</span><span class="token punctuation">]</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Api</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">id</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">ID</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">titel</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">versie</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">String</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">organisatie</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token class-name">Organisatie</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token keyword">type</span><span class="token plain"> </span><span class="token class-name">Query</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">organisatie</span><span class="token punctuation">(</span><span class="token attr-name">id</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">ID</span><span class="token operator">!</span><span class="token punctuation">)</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token class-name">Organisatie</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">organisaties</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token class-name">Organisatie</span><span class="token operator">!</span><span class="token punctuation">]</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token attr-name">apis</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token class-name">Api</span><span class="token operator">!</span><span class="token punctuation">]</span><span class="token operator">!</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Het uitroepteken markeert verplichte (non-nullable) velden. Let op de relaties:
een <code>Organisatie</code> heeft <code>apis</code>, en een <code>Api</code> verwijst terug naar zijn
<code>organisatie</code>. Het schema vormt zo een <em>graph</em> van samenhangende types; vandaar
de naam.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="queries">Queries<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#queries" class="hash-link" aria-label="Direct link naar Queries" title="Direct link naar Queries" translate="no">​</a></h3>
<p>De client stelt een query samen die qua vorm het gewenste antwoord spiegelt:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property-query">organisatie</span><span class="token punctuation">(</span><span class="token attr-name">id</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"min-bzk"</span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token property">naam</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token object">apis</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token property">titel</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token property">versie</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>De server antwoordt met exact de gevraagde velden, niets meer en niets minder:</p>
<div class="language-json codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-json codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property">"data"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token property">"organisatie"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token property">"naam"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string">"Ministerie van BZK"</span><span class="token punctuation">,</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token property">"apis"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation">[</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">        </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">"titel"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string">"Adressenregister API"</span><span class="token punctuation">,</span><span class="token plain"> </span><span class="token property">"versie"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string">"2.1.0"</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">        </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">"titel"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string">"Organisaties API"</span><span class="token punctuation">,</span><span class="token plain"> </span><span class="token property">"versie"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string">"1.0.3"</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token punctuation">]</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="variabelen">Variabelen<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#variabelen" class="hash-link" aria-label="Direct link naar Variabelen" title="Direct link naar Variabelen" translate="no">​</a></h3>
<p>In de praktijk schrijven clients geen letterlijke waarden in de query, maar
benoemde operaties met variabelen:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">query</span><span class="token plain"> </span><span class="token definition-query function">ApisVanOrganisatie</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token scalar">ID</span><span class="token operator">!</span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property-query">organisatie</span><span class="token punctuation">(</span><span class="token attr-name">id</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token property">naam</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token object">apis</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">      </span><span class="token property">titel</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<div class="language-json codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-json codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token punctuation">{</span><span class="token plain"> </span><span class="token property">"id"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string">"min-bzk"</span><span class="token plain"> </span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>De query wordt daarmee een herbruikbaar, valideerbaar document dat los van de
invoer bestaat. Onthoud deze vorm: in deel 2 zien we dat zulke benoemde
documenten de basis vormen voor beheersmaatregelen zoals persisted queries.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="mutations-en-subscriptions">Mutations en subscriptions<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#mutations-en-subscriptions" class="hash-link" aria-label="Direct link naar Mutations en subscriptions" title="Direct link naar Mutations en subscriptions" translate="no">​</a></h3>
<p>Schrijfoperaties heten <em>mutations</em>. Ze zijn in het schema expliciet gescheiden
van queries en geven, net als queries, precies de gevraagde velden terug:</p>
<div class="language-graphql codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-graphql codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token keyword">mutation</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token property-query property-mutation">registreerApi</span><span class="token punctuation">(</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token attr-name">input</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"> </span><span class="token attr-name">titel</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"Vergunningen API"</span><span class="token punctuation">,</span><span class="token plain"> </span><span class="token attr-name">organisatieId</span><span class="token punctuation">:</span><span class="token plain"> </span><span class="token string">"gm0363"</span><span class="token plain"> </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">)</span><span class="token plain"> </span><span class="token punctuation">{</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token property">id</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">    </span><span class="token property">titel</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token punctuation">}</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token punctuation">}</span><br></div></code></pre></div></div>
<p>Daarnaast kent GraphQL <em>subscriptions</em>: de server pusht wijzigingen naar de
client zodra die zich voordoen, een patroon dat aansluit bij
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/architectuur/eda">Event Driven Architecture</a>. In
de rest van deze serie richten we ons op het bevragen van data; het ontwerp van
mutations en subscriptions laten we verder buiten beschouwing.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="resolvers">Resolvers<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#resolvers" class="hash-link" aria-label="Direct link naar Resolvers" title="Direct link naar Resolvers" translate="no">​</a></h3>
<p>Aan de serverkant wordt elk veld ingevuld door een <em>resolver</em>: een functie die
weet hoe de waarde van dat ene veld opgehaald moet worden. Hoe de data achter de
schermen is opgeslagen (één database, meerdere services, een externe API) is
voor de client onzichtbaar. Dat maakt GraphQL ook geschikt als
<em>orkestratielaag</em>: een schema dat gegevens uit meerdere bestaande API's
combineert en in samenhang bevraagbaar maakt, zonder die bronnen te vervangen.
Op dat patroon komen we in deel 4 terug.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="introspectie">Introspectie<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#introspectie" class="hash-link" aria-label="Direct link naar Introspectie" title="Direct link naar Introspectie" translate="no">​</a></h3>
<p>Een GraphQL-API is zelfbeschrijvend: via een standaard introspectie-query kan
elke client het volledige schema opvragen. Daarop bouwt een rijk ecosysteem van
tooling, zoals interactieve explorers (GraphiQL), automatische documentatie en
codegeneratie voor clients.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="dezelfde-vraag-in-rest">Dezelfde vraag in REST<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#dezelfde-vraag-in-rest" class="hash-link" aria-label="Direct link naar Dezelfde vraag in REST" title="Direct link naar Dezelfde vraag in REST" translate="no">​</a></h2>
<p>Hoe zou de bovenstaande informatiebehoefte er met een klassieke REST-API
uitzien? Waarschijnlijk ongeveer zo:</p>
<div class="language-http codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-http codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token plain">GET /organisaties/min-bzk</span><br></div><div class="token-line"><span class="token plain">GET /organisaties/min-bzk/apis</span><br></div></code></pre></div></div>
<p>De eerste call levert de volledige organisatie-representatie op, inclusief
adresgegevens, contactinformatie en andere velden die we in dit scenario niet
nodig hebben. Dat heet <em>overfetching</em>. Levert de tweede call alleen
samenvattingen op, dan is per API mogelijk nog een extra call nodig voor de
details: <em>underfetching</em>, met meerdere roundtrips tot gevolg.</p>
<p>Dit is het probleem waarvoor GraphQL is ontworpen. In één request, in één
roundtrip, precies de benodigde data, ongeacht hoeveel types de vraag raakt.
Voor Facebook, met trage mobiele netwerken en een nieuws-feed vol diep geneste,
onderling verbonden data, was dat de bestaansreden.</p>
<p>REST kan hetzelfde bereiken, met zorgvuldig ontworpen resources, <code>fields</code>- of
<code>expand</code>-parameters, of een specifiek op een scherm toegesneden endpoint. Het
verschil is dat GraphQL deze flexibiliteit <em>generiek</em> biedt, terwijl je haar in
REST per geval ontwerpt. Op die afweging komen we in deel 2 uitgebreid terug.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="een-ander-paradigma-geen-betere-rest">Een ander paradigma, geen "betere REST"<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#een-ander-paradigma-geen-betere-rest" class="hash-link" aria-label="Direct link naar Een ander paradigma, geen &quot;betere REST&quot;" title="Direct link naar Een ander paradigma, geen &quot;betere REST&quot;" translate="no">​</a></h2>
<p>Het is verleidelijk GraphQL te zien als "REST, maar dan handiger". Dat doet
beide tekort. Het verschil wordt zichtbaar zodra je naar het HTTP-verkeer kijkt.
Een minimale variant van de benoemde operatie uit de paragraaf over variabelen
gaat zo over de lijn:</p>
<div class="language-http codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-http codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token plain">POST /graphql HTTP/1.1</span><br></div><div class="token-line"><span class="token plain">Content-Type: application/json</span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain">{</span><br></div><div class="token-line"><span class="token plain">  "query": "query Naam($id: ID!) { organisatie(id: $id) { naam } }",</span><br></div><div class="token-line"><span class="token plain">  "variables": { "id": "min-bzk" }</span><br></div><div class="token-line"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>Eén endpoint, vrijwel altijd <code>POST</code>, en de eigenlijke vraag zit in de body. Voor
het netwerk is elk GraphQL-request identiek; wat er gevraagd wordt, is alleen
zichtbaar voor wie de body parseert. Zet de twee modellen naast elkaar:</p>
<ul>
<li class=""><strong>REST</strong> modelleert <em>resources</em> en leunt op de semantiek van HTTP: werkwoorden
(<code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>DELETE</code>), statuscodes, unieke URI's per resource,
cache-headers en content negotiation. Het netwerk "begrijpt" een REST-API: een
cache, proxy of loadbalancer kan zinvol reageren op wat er langskomt.</li>
<li class=""><strong>GraphQL</strong> modelleert een <em>graph</em> van types en gebruikt HTTP vooral als
transport. Vrijwel al het verkeer gaat via één endpoint (meestal
<code>POST /graphql</code>), antwoorden komen doorgaans terug met status <code>200 OK</code>, ook
als er iets misging, en fouten staan als data in de responsebody.</li>
</ul>
<p>In onze eerdere blogpost over
<a class="" href="https://developer.overheid.nl/blog/2025/07/10/openapi-31-in-zicht">OpenAPI 3.1</a> constateerden we dit al:
GraphQL gebruikt HTTP wel als protocol, maar volgt niet het HTTP-model waarop
specificaties als
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/openapi-specification">OpenAPI</a> zijn
gebaseerd. De
<a href="https://graphql.github.io/graphql-over-http/" target="_blank" rel="noopener noreferrer" class="">GraphQL over HTTP-specificatie</a>,
die vastlegt hoe GraphQL-verkeer over HTTP hoort te lopen, is op het moment van
schrijven (medio 2026) nog een working draft; het transportgedrag ligt formeel
dus nog niet vast.</p>
<p>Dit paradigmaverschil is de rode draad van deze serie. Vrijwel elk voordeel én
vrijwel elke uitdaging van GraphQL is erop terug te voeren: wat je wint aan
flexibiliteit in de bevraging, moet je elders opnieuw organiseren. Denk aan
caching, autorisatie en beheersing van de belasting.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-rest-van-deze-serie">De rest van deze serie<a href="https://developer.overheid.nl/blog/2026/07/30/graphql-1-introductie#de-rest-van-deze-serie" class="hash-link" aria-label="Direct link naar De rest van deze serie" title="Direct link naar De rest van deze serie" translate="no">​</a></h2>
<p>In de komende delen gaan we de diepte in:</p>
<ul>
<li class=""><strong><a class="" href="https://developer.overheid.nl/blog/2026/08/18/graphql-2-flexibiliteit-en-limieten">Deel 2</a></strong> behandelt
de kernbelofte van GraphQL (flexibel bevragen als oplossing voor over- en
underfetching) en de prijs die daar tegenover staat: onvoorspelbare
performance en een groter aanvalsoppervlak, en hoe je daar limieten aan stelt.</li>
<li class=""><strong><a class="" href="https://developer.overheid.nl/blog/2026/08/26/graphql-3-schema-ontwerp">Deel 3</a></strong> duikt in de praktijk
van schema-ontwerp: paginering, filtering, union types, custom scalars,
autorisatie en content negotiation.</li>
<li class=""><strong><a class="" href="https://developer.overheid.nl/blog/2026/09/02/graphql-4-afwegingskader">Deel 4</a></strong> brengt alles samen in
een afwegingskader: wanneer is GraphQL een logische keuze, en wanneer ben je
met REST beter af, zeker binnen de context van de Nederlandse overheid en de
ADR.</li>
</ul>
<p>Een compacte referentie over GraphQL, met de status binnen de overheid en de
belangrijkste specificaties, staat in de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/graphql">kennisbank</a>.</p>]]></content>
        <author>
            <name>Joost Farla</name>
        </author>
        <category label="API" term="API"/>
        <category label="API Design" term="API Design"/>
        <category label="GraphQL" term="GraphQL"/>
        <category label="REST API design" term="REST API design"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Van OpenAPI-specificatie naar startbare API-app]]></title>
        <id>https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates</id>
        <link href="https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates"/>
        <updated>2026-07-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Met de codegen templates van developer.overheid.nl kun je vanuit een
gevalideerde OpenAPI-specificatie een startbare API-applicatie genereren in
meerdere programmeertalen. Dat maakt design-first werken concreter: eerst het
contract goed krijgen, daarna sneller naar werkende code.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="Abstracte weergave van het proces" src="https://developer.overheid.nl/assets/images/codegen-52848dace7b5847724724096ef818494.png" width="1200" height="630" class="img_rVHu"></p>
<p>Een goede API begint niet bij de controller, maar bij het contract. In de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/tutorials/bouw-een-api">Bouw een API-tutorial</a>
laten we zien hoe je vanuit een gevalideerde OpenAPI Specification servercode
genereert. Tot nu toe lag de nadruk daar vooral op een Express-template als
demonstratie. Inmiddels hebben we de template-repository uitgebreid met meer
runtimes en programmeertalen.</p>
<p>Dat klinkt misschien als een kleine toolingstap, maar het raakt een praktisch
probleem dat veel teams herkennen: hoe kom je van een nette OAS naar een
applicatie die dezelfde afspraken ook echt afdwingt?</p>
<p>Dit artikel zoomt bewust in op één concrete stap: codegeneratie na het ontwerpen
en valideren van je API-contract. Niet de hele toolingketen, maar de vraag wat
er gebeurt zodra je OAS klaar is en je team met implementeren wil beginnen. Voor
de bredere gedachte achter generators, validators en agents verwijzen we naar
<a class="" href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop">Tools in the loop</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="waarom-templates">Waarom templates?<a href="https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates#waarom-templates" class="hash-link" aria-label="Direct link naar Waarom templates?" title="Direct link naar Waarom templates?" translate="no">​</a></h2>
<p>OpenAPI Generator kan code genereren voor tientallen talen en frameworks. Dat is
handig, maar de standaard output is generiek. Voor een API bij de Nederlandse
overheid wil je juist dat de gegenereerde applicatie aansluit op de manier
waarop we API's ontwerpen:</p>
<ul>
<li class="">de OpenAPI-specificatie is het contract;</li>
<li class="">request-validatie gebeurt op basis van dat contract;</li>
<li class="">foutmeldingen gebruiken <code>application/problem+json</code>;</li>
<li class="">de gegenereerde code heeft duidelijke plekken voor businesslogica;</li>
<li class="">de oorspronkelijke OAS blijft gepubliceerd bij de applicatie;</li>
<li class="">de output is geschikt als startpunt voor implementatie, niet als losstaande
eindoplossing.</li>
</ul>
<p>Daarvoor gebruiken we de
<a href="https://github.com/developer-overheid-nl/codegen-templates" target="_blank" rel="noopener noreferrer" class="">codegen-templates repository</a>.
Die bevat aangepaste templates bovenop OpenAPI Generator. Je gebruikt dus nog
steeds de bekende generator, maar met projecttemplates die beter passen bij de
design-first workflow op developer.overheid.nl.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="wat-kun-je-ermee">Wat kun je ermee?<a href="https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates#wat-kun-je-ermee" class="hash-link" aria-label="Direct link naar Wat kun je ermee?" title="Direct link naar Wat kun je ermee?" translate="no">​</a></h2>
<p>De basisflow is hetzelfde als in de tutorial:</p>
<ol>
<li class="">Maak of onderhoud je OpenAPI-specificatie.</li>
<li class="">Valideer die specificatie met de DON Checker of ADR-ruleset.</li>
<li class="">Bundel externe <code>$ref</code>s, zodat de generator een zelfstandig bestand krijgt.</li>
<li class="">Genereer een applicatie met een template.</li>
<li class="">Implementeer de businesslogica op de daarvoor bedoelde plekken.</li>
</ol>
<p>Bijvoorbeeld:</p>
<div class="language-sh codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-sh codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token plain">npx @redocly/cli bundle ./openapi.json </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">--output</span><span class="token plain"> openapi.bundled.json </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">--ext</span><span class="token plain"> json</span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain">npx @developer-overheid-nl/don-checker@latest validate </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">--ruleset</span><span class="token plain"> adr-21 </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">--input</span><span class="token plain"> openapi.bundled.json</span><br></div><div class="token-line"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line"><span class="token plain"></span><span class="token function">git</span><span class="token plain"> clone https://github.com/developer-overheid-nl/codegen-templates.git</span><br></div></code></pre></div></div>
<p>Daarna kies je de runtime die past bij je team of applicatie.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="beschikbare-templates">Beschikbare templates<a href="https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates#beschikbare-templates" class="hash-link" aria-label="Direct link naar Beschikbare templates" title="Direct link naar Beschikbare templates" translate="no">​</a></h2>
<p>Op dit moment bevat de repository templates voor:</p>
<table><thead><tr><th>Template</th><th>Runtime</th><th>Waarvoor handig</th></tr></thead><tbody><tr><td><code>nodejs-express-server</code></td><td>Node.js + Express</td><td>Een eenvoudige serverstub of mockserver, vergelijkbaar met de tutorial.</td></tr><tr><td><code>nestjs-fastify</code></td><td>NestJS + Fastify</td><td>Een TypeScript-app met abstracte API classes, runtime-validatie, mock mode en problem-details.</td></tr><tr><td><code>go-gin-template</code></td><td>Go + Gin</td><td>Een compacte Go serverstub met interfaces per API-groep.</td></tr><tr><td><code>java-spring-boot</code></td><td>Java + Spring Boot</td><td>Een Spring Boot-app met delegate interfaces, Bean Validation en problem-details.</td></tr><tr><td><code>rust-axum-template</code></td><td>Rust + Axum</td><td>Een Rust crate met Axum-router, API traits en request-validatie.</td></tr><tr><td><code>python-fastapi-template</code></td><td>Python + FastAPI</td><td>Een FastAPI-app met Pydantic-validatie, routers per API-groep en problem-details.</td></tr></tbody></table>
<p>De Node.js- en NestJS-templates zijn het meest uitgewerkt. De Go-, Java-, Rust-
en Python-templates zijn toegevoegd als basisvarianten en moeten nog verder in
echte API-applicaties worden beproefd.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="wat-levert-de-gegenereerde-code-op">Wat levert de gegenereerde code op?<a href="https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates#wat-levert-de-gegenereerde-code-op" class="hash-link" aria-label="Direct link naar Wat levert de gegenereerde code op?" title="Direct link naar Wat levert de gegenereerde code op?" translate="no">​</a></h2>
<p>De templates genereren geen complete productieapplicatie. Ze geven je een
startpunt waarin het saaie en foutgevoelige werk al is gedaan.</p>
<p>Denk aan:</p>
<ul>
<li class="">routes die overeenkomen met de paden uit je OAS;</li>
<li class="">modellen/types op basis van de schemas;</li>
<li class="">request-validatie voor parameters en bodies;</li>
<li class="">controllers, services, delegates, traits of base classes waar je eigen code
aan koppelt;</li>
<li class="">standaardresponses voor ontbrekende implementaties;</li>
<li class="">publicatie van het broncontract of runtime OpenAPI-document, bijvoorbeeld via
<code>/openapi.yaml</code> of <code>/openapi.json</code>.</li>
</ul>
<p>De belangrijkste winst zit in de scheiding tussen contract en implementatie. De
OAS bepaalt welke operatie bestaat, welke parameters geldig zijn en welke
schemas over de lijn gaan. De gegenereerde code volgt dat contract. Je team kan
zich daarna richten op de domeinlogica: databases, autorisatie, integraties,
logging, monitoring en testen.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="een-voorbeeld-nestjs-of-fastapi">Een voorbeeld: NestJS of FastAPI<a href="https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates#een-voorbeeld-nestjs-of-fastapi" class="hash-link" aria-label="Direct link naar Een voorbeeld: NestJS of FastAPI" title="Direct link naar Een voorbeeld: NestJS of FastAPI" translate="no">​</a></h2>
<p>Voor een NestJS-app ziet genereren er bijvoorbeeld zo uit:</p>
<div class="language-sh codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-sh codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token plain">npx @openapitools/openapi-generator-cli generate </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-i</span><span class="token plain"> openapi.bundled.json </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-g</span><span class="token plain"> typescript-nestjs-server </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-o</span><span class="token plain"> ./generated-api-nestjs </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-t</span><span class="token plain"> ./codegen-templates/nestjs-fastify </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-c</span><span class="token plain"> ./codegen-templates/nestjs-fastify/generator-config.yaml </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  --skip-validate-spec </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  --additional-properties</span><span class="token operator">=</span><span class="token plain">npmName</span><span class="token operator">=</span><span class="token plain">generated-api-nestjs,npmVersion</span><span class="token operator">=</span><span class="token number">1.0</span><span class="token plain">.0,nestVersion</span><span class="token operator">=</span><span class="token number">11.0</span><span class="token plain">.0,rxjsVersion</span><span class="token operator">=</span><span class="token number">7.8</span><span class="token plain">.2,tsVersion</span><span class="token operator">=</span><span class="token number">5.9</span><span class="token plain">.3,nodeVersion</span><span class="token operator">=</span><span class="token number">22.0</span><span class="token plain">.0</span><br></div></code></pre></div></div>
<p>De template maakt abstracte API classes en controllers. Je koppelt je eigen
implementaties via de gegenereerde module. Ontbreekt een implementatie, dan
krijg je standaard een <code>501 application/problem+json</code> response. Dat is handig in
de ontwikkeling: je ziet direct welke operatie nog geen echte invulling heeft.</p>
<p>Voor Python/FastAPI is het patroon vergelijkbaar:</p>
<div class="language-sh codeBlockContainer_Emz1 theme-code-block"><div class="codeBlockContent_An2N"><pre tabindex="0" class="prism-code language-sh codeBlock_l64l thin-scrollbar"><code class="codeBlockLines_uBx2"><div class="token-line"><span class="token plain">npx @openapitools/openapi-generator-cli generate </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-i</span><span class="token plain"> openapi.bundled.json </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-g</span><span class="token plain"> python-fastapi </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-o</span><span class="token plain"> ./generated-api-python </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-t</span><span class="token plain"> ./codegen-templates/python-fastapi-template </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  </span><span class="token parameter variable">-c</span><span class="token plain"> ./codegen-templates/python-fastapi-template/generator-config.yaml </span><span class="token punctuation">\</span><span class="token plain"></span><br></div><div class="token-line"><span class="token plain">  --additional-properties</span><span class="token operator">=</span><span class="token plain">packageName</span><span class="token operator">=</span><span class="token plain">generated_api_python,packageVersion</span><span class="token operator">=</span><span class="token number">1.0</span><span class="token plain">.0,serverPort</span><span class="token operator">=</span><span class="token number">1337</span><br></div></code></pre></div></div>
<p>FastAPI en Pydantic verzorgen de request-validatie. De template zet
validatiefouten om naar <code>400 application/problem+json</code> en maakt per API-groep
base classes waar je implementatie van kan erven.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="waarom-is-dit-handig">Waarom is dit handig?<a href="https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates#waarom-is-dit-handig" class="hash-link" aria-label="Direct link naar Waarom is dit handig?" title="Direct link naar Waarom is dit handig?" translate="no">​</a></h2>
<p>Codegeneratie wordt soms gezien als iets dat vooral boilerplate bespaart. Dat
doet het ook, maar voor API-ontwikkeling is het belangrijker dat het de
werkwijze expliciet maakt.</p>
<p>Als je eerst code schrijft en daarna documentatie genereert, ontstaat er snel
discussie over wat leidend is. Is de controller de waarheid? De documentatie?
Een test? Een wiki? Bij design-first is de OAS de afspraak. De templates helpen
om die afspraak niet alleen te publiceren, maar ook te gebruiken in de
applicatie zelf.</p>
<p>Dat heeft een paar voordelen:</p>
<ul>
<li class="">reviewers kunnen eerst het contract beoordelen voordat er implementatiedetails
bijkomen;</li>
<li class="">frontend- en backendteams kunnen eerder parallel werken;</li>
<li class="">mockservers en gegenereerde stubs maken testen eerder mogelijk;</li>
<li class="">afwijkingen van de API Design Rules worden eerder gevonden;</li>
<li class="">teams kunnen in verschillende talen werken zonder de API-werkwijze telkens
opnieuw uit te vinden.</li>
</ul>
<p>Voor overheidsorganisaties is dat extra relevant. API's worden vaak door andere
organisaties gebruikt, soms jaren nadat het oorspronkelijke team alweer
veranderd is. Een duidelijk contract en voorspelbare foutafhandeling maken zo'n
API beter beheerbaar.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="geen-magie-wel-een-betere-start">Geen magie, wel een betere start<a href="https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates#geen-magie-wel-een-betere-start" class="hash-link" aria-label="Direct link naar Geen magie, wel een betere start" title="Direct link naar Geen magie, wel een betere start" translate="no">​</a></h2>
<p>De templates nemen niet alles over. Je moet nog steeds nadenken over security,
autorisatie, logging, performance, datamodellering en beheer. Je moet ook de
gegenereerde code testen in je eigen stack. Zeker de nieuwere templates vragen
nog praktijkervaring en bijdragen uit projecten.</p>
<p>Maar ze verlagen wel de drempel om goed te beginnen. In plaats van een leeg
frameworkproject krijg je een applicatie die al weet welke operaties bestaan,
welke input geldig is en waar je de implementatie moet plaatsen.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="meedoen">Meedoen<a href="https://developer.overheid.nl/blog/2026/07/16/api-codegen-templates#meedoen" class="hash-link" aria-label="Direct link naar Meedoen" title="Direct link naar Meedoen" translate="no">​</a></h2>
<p>De templates zijn open source. Gebruik ze, probeer ze uit op een bestaande OAS
en open vooral issues of pull requests als je iets mist of verbetert.</p>
<a class="nl-link rhc-link" href="https://github.com/developer-overheid-nl/codegen-templates"><p>Bekijk de codegen templates op GitHub</p><span class="utrecht-icon" role="presentation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-arrow-narrow-right"><path d="M5 12l14 0"></path><path d="M15 16l4 -4"></path><path d="M15 8l4 4"></path></svg></span></a>
<br>
<a class="nl-link rhc-link" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/tutorials/bouw-een-api/genereer-api-code"><p>Lees de tutorial over API-code genereren</p><span class="utrecht-icon" role="presentation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-arrow-narrow-right"><path d="M5 12l14 0"></path><path d="M15 16l4 -4"></path><path d="M15 8l4 4"></path></svg></span></a>]]></content>
        <author>
            <name>Matthijs Hovestad</name>
        </author>
        <category label="API" term="API"/>
        <category label="OpenAPI" term="OpenAPI"/>
        <category label="API Design" term="API Design"/>
        <category label="Codegen" term="Codegen"/>
        <category label="API Design Rules" term="API Design Rules"/>
        <category label="developer.overheid.nl" term="developer.overheid.nl"/>
        <category label="Open Source" term="Open Source"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tools in the loop: "human in the loop" krijgt hulp]]></title>
        <id>https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop</id>
        <link href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop"/>
        <updated>2026-07-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Voor wie AI inzet om overheidssoftware te bouwen, houden we naast de mens ook de tools in de loop: generators die het zware werk doen en validators die de regels bewaken. Zo verschuift het naleven van standaarden van menselijke oplettendheid naar deterministische tooling die je kunt vertrouwen.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="Abstracte weergave van het proces" src="https://developer.overheid.nl/assets/images/tools-in-the-loop-b5da7024bb82f79728e06bebdf03cd13.png" width="2400" height="1000" class="img_rVHu"></p>
<p>"Human in the loop" is inmiddels het standaardantwoord op bijna elke zorg rond
AI. Maar voor wie AI inzet om overheidssoftware te bouwen, is het verstandig om
naast de mens ook <em>tools</em> in de loop houden: generators die het zware werk doen
en validators die de regels bewaken. Zo verschuift het naleven van standaarden
van de oplettendheid van een mens en de welwillendheid van AI naar tooling die
je kunt vertrouwen. Hoe dat samenwerkt, en aan welk arsenaal aan skills,
generators, validators en andere tools we werken, lees je in deze post.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>Als je AI gebruikt om software te bouwen, houd dan naast de mens ook onze
<em>tools</em> in de loop:</p><ul>
<li class=""><strong>Generators</strong> doen het zware, repetitieve werk (boilerplate,
projectstructuur) en zijn deterministisch.</li>
<li class=""><strong>Validators</strong> beantwoorden de waarheidsvraag "Voldoet dit aan de regels?".
Niet het model, maar een tool met een vaste set regels.</li>
<li class="">De <strong>command line</strong> is de natuurlijke interface voor agents: de agent itereert
op exit codes tot de checker <code>valid</code> teruggeeft.</li>
<li class="">AI is zo een hulpmiddel voor de input, niet het orakel dat de waarheid
bepaalt.</li>
</ul><p>Dit valt of staat met <strong>standaarden</strong>: elke afspraak is een stukje waarheid dat
je in betrouwbare tooling stopt zodat AI het niet zelf hoeft te verzinnen.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="validators-en-generators-worden-steeds-belangrijker">Validators en generators worden steeds belangrijker<a href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop#validators-en-generators-worden-steeds-belangrijker" class="hash-link" aria-label="Direct link naar Validators en generators worden steeds belangrijker" title="Direct link naar Validators en generators worden steeds belangrijker" translate="no">​</a></h2>
<p>Je zou kunnen denken dat in een wereld waarin een AI-agent "gewoon de code
schrijft" de behoefte aan generators en validators afneemt. Het
tegenovergestelde is waar. Juist omdat een taalmodel plausibel-ogend werk
produceert dat tóch fout kan zijn, wordt het werk dat je níet aan het model wilt
overlaten belangrijker dan ooit.</p>
<p>Dat werk bestaat uit twee soorten. Het zware, repetitieve werk, zoals het
genereren van boilerplates en het opzetten van een projectstructuur, dat kun je
een generator laten doen. Die is deterministisch en doet elke keer hetzelfde. En
de waarheidsvraag, "Voldoet dit aan de regels die wij hanteren?", kun je door
een validator laten beantwoorden. Niet AI, niet de mens, maar een tool met een
vaste set regels.</p>
<p>Bovendien hoeft AI zo minder zelf te "bedenken". Dat scheelt hallucinaties en
het verbrandt geen onnodige tokens. Het model doet waar het goed in is, namelijk
taal en intentie interpreteren, en de tools doen waar zij goed in zijn.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="cli-als-natuurlijke-interface-voor-ai-agents">CLI als natuurlijke interface voor AI-agents<a href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop#cli-als-natuurlijke-interface-voor-ai-agents" class="hash-link" aria-label="Direct link naar CLI als natuurlijke interface voor AI-agents" title="Direct link naar CLI als natuurlijke interface voor AI-agents" translate="no">​</a></h2>
<p>Agents leven op de command line. Ze roepen tools aan, lezen de output, en
bepalen op basis daarvan hun volgende stap. Dat maakt een CLI de meest
natuurlijke interface die je een agent kunt aanbieden: deterministisch,
scriptbaar, aan elkaar te knopen, en met een exit code en gestructureerde output
waar een agent direct op kan itereren.</p>
<p>Daarom hebben onze tools sinds kort allemaal een command line interface
gekregen, van de generators tot de checkers. Een invalid output uit onze checker
is daarmee een exit status: de agent leest het, ziet wat er mis is, past het aan
en draait de checker opnieuw. Daar draait de hele validatieloop op, zonder dat
er een mens tussen hoeft te zitten.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="hoe-alles-samenwerkt">Hoe alles samenwerkt<a href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop#hoe-alles-samenwerkt" class="hash-link" aria-label="Direct link naar Hoe alles samenwerkt" title="Direct link naar Hoe alles samenwerkt" translate="no">​</a></h2>
<p>Vanuit developer.overheid.nl bieden we de volgende features (deels al, deels
binnenkort) aan. De rolverdeling:</p>
<ul>
<li class=""><strong>Schema Register.</strong> Een register van herbruikbare JSON schema's waar straks
niet alleen mensen, maar ook agents uit kunnen putten. In plaats van schema's
te verzinnen, verwijst de agent naar wat er al is. Met de komende upgrade naar
<a class="" href="https://developer.overheid.nl/blog/2025/07/10/openapi-31-in-zicht">OpenAPI 3.1</a> zijn deze schema's direct
te gebruiken in OAS-documenten. Dit register is momenteel in ontwikkeling; we
verwachten dit snel te kunnen lanceren.</li>
<li class=""><strong><a href="https://github.com/developer-overheid-nl/skills-marketplace" target="_blank" rel="noopener noreferrer" class="">Agent Skills</a>.</strong>
Hiermee geven we agents instructies mee: welke tool, op welk moment, in welke
volgorde. De skill is wat de agent dwingt om onze tooling te gebruiken in
plaats van zelf te improviseren. Deze zijn in beta en nog volop in onderzoek,
dus gebruiken op eigen risico! Eerder schreven we al over
<a class="" href="https://developer.overheid.nl/blog/2026/03/25/skills">hoe je standaarden in je AI-assistant laadt</a>.</li>
<li class=""><strong><a href="https://developer-overheid-nl.github.io/oas-generator" target="_blank" rel="noopener noreferrer" class="">OAS Generator</a>.</strong>
Genereert een boilerplate OpenAPI-document op basis van een <code>input.json</code>. Die
boilerplate is al ADR-conform van opzet, dus de agent begint niet van scratch
maar met een correct startpunt.</li>
<li class=""><strong><a href="https://developer-overheid-nl.github.io/don-checker" target="_blank" rel="noopener noreferrer" class="">Checker</a>.</strong> Onze
linter/validator die een document toetst aan een ruleset, bijvoorbeeld de
ADR-ruleset voor een OAS of de publiccode-ruleset voor
<a class="" href="https://developer.overheid.nl/kennisbank/open-source/standaarden/publiccode-yml"><code>publiccode.yml</code></a>. Bij
<code>valid</code> mag de pijplijn door, bij <code>invalid</code> moet er opnieuw geïtereerd worden.
Dit is de spil waar de hele kwaliteitsborging om draait.</li>
<li class=""><strong><a href="https://github.com/developer-overheid-nl/codegen-templates" target="_blank" rel="noopener noreferrer" class="">Codegen Templates</a>.</strong>
Eigen <a href="https://openapi-generator.tech/" target="_blank" rel="noopener noreferrer" class="">OpenAPI Generator</a> templates, zodat de
gegenereerde servercode voor API's aansluit op de API Design Rules en andere
overheidsstandaarden. Momenteel hebben we een aantal smaken in de aanbieding,
waaronder voor Java, Go, Node.js, Rust en Python.</li>
<li class=""><strong><a class="" href="https://developer.overheid.nl/kennisbank/open-source/tutorials/tutorial-repo-docs-generator">Repo Docs Generator</a>.</strong>
Genereert de standaard repo-documentatie: een <code>README.md</code>, <code>CONTRIBUTING.md</code>,
<code>CODE_OF_CONDUCT.md</code>, <code>LICENSE</code>, <code>SECURITY.md</code>, <code>CHANGELOG.md</code> en een
<code>publiccode.yml</code>. In één keer nette, consistente templates in plaats van
handmatig samengeraapte bestanden.</li>
</ul>
<p>De AI doet in dit geheel maar twee dingen: de <code>input.json</code> vullen, een vast
formaat dat het model kent, en via dialoog met de gebruiker die input compleet
maken. Pas als de input volledig is, wordt er daadwerkelijk gegenereerd.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="generator-en-checker-zijn-complementair">Generator en checker zijn complementair<a href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop#generator-en-checker-zijn-complementair" class="hash-link" aria-label="Direct link naar Generator en checker zijn complementair" title="Direct link naar Generator en checker zijn complementair" translate="no">​</a></h2>
<p>Een terechte vraag is: als de generator al een boilerplate maakt conform de
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/api-design-rules">API Design Rules (ADR)</a>,
en de agent borduurt voort op wat er al staat, heb je die checker dan überhaupt
nog nodig?</p>
<p>Het antwoord is ja, en het waarom is meteen het sterkste argument vóór deze
opzet. Het klopt dat een agent geneigd is om voort te borduren op een bestaand,
intern consistent document. Een schone boilerplate werkt als voorbeeld: de agent
ziet hoe wij naar het register verwijzen, hoe we fouten modelleren, welke naming
we hanteren, en trekt dat door. Dat is precies waarom je met een goede
boilerplate begint. Het vernauwt de output, scheelt tokens en verkleint de kans
op afwijkingen.</p>
<p>Maar het is geen garantie. Naarmate een document groeit, valt de oorspronkelijke
boilerplate buiten het effectieve aandachtsvenster van het model. Voeg je
functionaliteit toe waar geen voorbeeld voor in het document staat, dan valt het
model terug op zijn trainingsdata, en die is niet ADR-conform. En over meerdere
bewerkingen heen kunnen kleine afwijkingen zich opstapelen.</p>
<p>Daarom zijn de generator en de checker geen overlap maar complementair. De
generator-boilerplate zorgt dat de checker bijna altijd meteen <code>valid</code>
teruggeeft. De checker is er voor de keren dat dat niet zo is, of als er na de
generatie nog wijzigingen aan de OAS doorgevoerd worden. Denk aan extra
endpoints, filters, etc. De checker handhaaft de harde grens die een taalmodel
statistisch nooit kan garanderen.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="een-overheids-api-bouwen">Een overheids-API bouwen<a href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop#een-overheids-api-bouwen" class="hash-link" aria-label="Direct link naar Een overheids-API bouwen" title="Direct link naar Een overheids-API bouwen" translate="no">​</a></h2>
<p>Tijd om te laten zien hoe die loop er in de praktijk uitziet. De onderstaande
flowchart toont het hele proces in één oogopslag; daaronder lopen we de stappen
langs.</p>
<!-- -->
<p>De gebruiker geeft de prompt "bouw een overheids-API". De juiste skill wordt
getriggerd en stuurt de agent door een vast proces. Eerst verzamelt de agent
input: deels door vragen te stellen aan de gebruiker, deels door het
schema-register te doorzoeken naar bruikbare, herbruikbare schema's. Het
resultaat is een complete <code>input.json</code>.</p>
<p>Die input gaat de OAS Generator in, die er een boilerplate <code>openapi.json</code> van
maakt. Vervolgens komt de Checker om de hoek kijken. Deze toetst het document
tegen de ADR-ruleset. Is het <code>invalid</code>, dan gaat het terug: de agent fixt de OAS
en draait de checker opnieuw, net zo lang tot het klopt. Óók als het document na
de generatie nog gewijzigd wordt dus.</p>
<p>Het belangrijkste aan dit plaatje is de lus rond de checker. De agent <em>kan</em> niet
langs de regels. Hij mag itereren, hij mag fouten maken, maar hij komt pas
verder als een deterministische tool groen licht geeft. De waarheid zit niet in
het model, maar in de checker.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-code-open-source-maken">De code open source maken<a href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop#de-code-open-source-maken" class="hash-link" aria-label="Direct link naar De code open source maken" title="Direct link naar De code open source maken" translate="no">​</a></h2>
<p>Precies hetzelfde patroon keert terug voor een ander prompt. De flowchart
hieronder laat zien hoe:</p>
<!-- -->
<p>"Maak dit open source" trapt een vergelijkbaar proces af: de juiste skill wordt
getriggerd, de agent verzamelt input en laat dat door de Repo Docs Generator
lopen. Die genereert in één keer de complete set repo-documentatie, van
<code>README.md</code> en <code>CONTRIBUTING.md</code> tot <code>CODE_OF_CONDUCT.md</code>, <code>LICENSE.md</code>,
<code>SECURITY.md</code>, <code>CHANGELOG.md</code> en een <code>publiccode.yml</code>. Vervolgens komt dezelfde
checker terug, nu met de publiccode-ruleset, die de <code>publiccode.yml</code> toetst. Is
het <code>invalid</code>, dan fixt de agent het bestand en draait de checker opnieuw, exact
dezelfde lus als bij het bouwen van de API. Saillant detail: als er reeds een
<code>README.md</code> is, zoals het geval is nadat je de OpenAPI-generator hebt gebruikt,
zal de agent deze aanpassen conform de template van de generator, welke de best
practices voor een <code>README.md</code> bevat.</p>
<p>In het geval van een bestaande codebase, instrueert de skill de agent om te
kijken naar de git remote, bestanden als <code>openapi.json</code> en het projectmanifest
(zoals een <code>package.json</code>, <code>pyproject.toml</code> of <code>pom.xml</code>) om daar de benodigde
input uit te halen. Doe je dit prompt vanuit de bestaande context, dan weet de
agent nog dingen uit de eerdere input. Denk hierbij bijvoorbeeld aan de
contactgegevens uit de zojuist gegenereerde OAS.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="standaarden">Standaarden<a href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop#standaarden" class="hash-link" aria-label="Direct link naar Standaarden" title="Direct link naar Standaarden" translate="no">​</a></h2>
<p>Er zit een randvoorwaarde onder dit hele verhaal, en die verdient het om
expliciet genoemd te worden: standaarden. De templates, generators en validators
uit deze blog bestaan alleen omdat er standaarden onder liggen waar we ze
tegenaan kunnen bouwen, de ADR, de publiccode-standaard, herbruikbare schema's.
Zonder een vaste set regels is er niets om een boilerplate op te baseren of een
document tegenaan te toetsen.</p>
<p>Hoe meer er gestandaardiseerd wordt, hoe nauwkeuriger we onze templates,
generators en validators kunnen maken. Elke afspraak die we vastleggen is een
stukje waarheid dat we uit het model kunnen halen en in deterministische tooling
kunnen stoppen. Standaardisatie is de fundering die betrouwbaar bouwen met AI
mogelijk maakt. Hoe steviger die fundering, hoe meer je met een gerust hart aan
de tools kunt overlaten.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="conclusie">Conclusie<a href="https://developer.overheid.nl/blog/2026/07/2/tools-in-the-loop#conclusie" class="hash-link" aria-label="Direct link naar Conclusie" title="Direct link naar Conclusie" translate="no">​</a></h2>
<p>Het resultaat is een proces dat reproduceerbaar en controleerbaar is. Dezelfde
input levert dezelfde output, en wat eruit komt voldoet aantoonbaar aan onze
regels, niet omdat een model toevallig goed gemutst was of een reviewer scherp
oplette, maar omdat een tool het heeft afgedwongen.</p>
<p>De rolverdeling is daarmee helder. Het taalmodel is de orkestrator die intentie
vertaalt naar input en tools aanroept, niet het orakel dat de waarheid bepaalt.
Generators doen het zware werk, validators bewaken de grenzen. En de mens blijft
gewoon in de loop, maar op het niveau waar menselijk oordeel telt: keuzes,
context, akkoord. Niet op het naleven van regels die een machine beter onthoudt.</p>
<p>Of je AI inzet is aan jou. Maar áls je het doet, houd dan niet alleen de mens in
de loop, maar óók beschikbare tools.</p>]]></content>
        <author>
            <name>Dimitri van Hees</name>
        </author>
        <category label="Artificial Intelligence" term="Artificial Intelligence"/>
        <category label="Large Language Model" term="Large Language Model"/>
        <category label="CLI" term="CLI"/>
        <category label="Validator" term="Validator"/>
        <category label="OpenAPI Specification" term="OpenAPI Specification"/>
        <category label="API Design Rules" term="API Design Rules"/>
        <category label="PublicCode" term="PublicCode"/>
        <category label="Open Source" term="Open Source"/>
        <category label="Standaarden" term="Standaarden"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[CIO-dag: Samen werken als oplossing voor Digitale Soevereiniteit en AI]]></title>
        <id>https://developer.overheid.nl/blog/2026/07/1/cio-dag</id>
        <link href="https://developer.overheid.nl/blog/2026/07/1/cio-dag"/>
        <updated>2026-07-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Op woensdag 24 juni was developer.overheid.nl te gast bij de Rijks CIO dag.
]]></summary>
        <content type="html"><![CDATA[<p>Om maar in de zelfde stroming te blijven als de Pitch voor het event zelf: Er
staat een nieuwe wind in het digitale landschap. Een wind aangewakkerd door
internationale incidenten, uitspraken, maar toch ook door een kritische blik op
'hoe zijn we hier gekomen'. Digitale souvereiniteit is de veilige haven waar we
op koersen, en de vloot is ondertussen onomkeerbaar in beweging gekomen.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="een-inmense-uitdaging-met-een-duidelijke-eerste-stap">Een inmense uitdaging, met een duidelijke eerste stap<a href="https://developer.overheid.nl/blog/2026/07/1/cio-dag#een-inmense-uitdaging-met-een-duidelijke-eerste-stap" class="hash-link" aria-label="Direct link naar Een inmense uitdaging, met een duidelijke eerste stap" title="Direct link naar Een inmense uitdaging, met een duidelijke eerste stap" translate="no">​</a></h2>
<p>De dag werd geopend met een stevige bezetting vanuit verschillende ministeries,
een voor een kwamen de uitdaging waar wij als land voor aan de lat staan naar
voren. De groei van AI, en de uitwerking daarvan. De Cloud strategie, Digitale
souvereiniteit, en veiligheid. Allemaal vragen waar het antwoord elke keer
eenduidig was: Samen. Samen werken, samen doen en samen ontwikkelen. Dit werd
ook beaamt door de `vreemde aap' in het gezelschap. Gedragswetenschapper
Patrick van Veen welke het gedrag van door hem onderzochte apen als spiegel voor
de aanwezigen hield om hen zo te laten zien wat 'samen werken' precies kan
betekenen.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="druk-bezochte-talks-lege-gangen">Druk bezochte talks, lege gangen.<a href="https://developer.overheid.nl/blog/2026/07/1/cio-dag#druk-bezochte-talks-lege-gangen" class="hash-link" aria-label="Direct link naar Druk bezochte talks, lege gangen." title="Direct link naar Druk bezochte talks, lege gangen." translate="no">​</a></h2>
<p>Een van de dingen die opviel (in tegenstelling tot andere grotere events) is dat
de wandelgangen en koffiehoekjes volstrekt uitgestorven waren tijdens de talks.
De verschillende stands op het Kennisplein werden dan wel goed bezocht tijdens
de pauzes, maar tijdens de talks was het vooral aan de standhouders zelf om
onderling een gesprek aan te gaan. Een positief iets, als je het mij vraagt.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="kennisplein">kennisplein<a href="https://developer.overheid.nl/blog/2026/07/1/cio-dag#kennisplein" class="hash-link" aria-label="Direct link naar kennisplein" title="Direct link naar kennisplein" translate="no">​</a></h2>
<p>Het kennisplein fungeert als vraagbaak en ook sociale lijm tussen de talks door.
Met 'standhouders' zoals Open source werken, developer.overheid.nl en ook Forum
Standarisatie was het voor geinspireerde luisteraars een peulenschil om
bijpassende expertise te vinden en vragen en discussies voort te zetten.
Robot-hond Adam, <code>tot leven</code> gewekt op een lokaal draaiend LLM trok bekijks, en
natuurlijk ook de nodige technische interesse. <code>Hoe werkt zo'n Lokaal LLM dan?</code>,
maar ook andere onderwerpen zoals de open source werkplek werden al snel
onderwerp van langdurige gesprekken tussen potentieele toekomstige gebruikers.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="vervolg">Vervolg<a href="https://developer.overheid.nl/blog/2026/07/1/cio-dag#vervolg" class="hash-link" aria-label="Direct link naar Vervolg" title="Direct link naar Vervolg" translate="no">​</a></h2>
<p>Ben jij CIO binnen de (bredere overheid) of vervul je een aanpalende rol, dan is
de volgende CIO dag wellicht ook iets voor jou. Deel ervaringen met collega's,
stel jou meest prangende vragen, of raak geinsprireerd door de vele sprekers. We
moeten het tenslotte samen met elkaar oplossen.</p>]]></content>
        <author>
            <name>Jan Klopper</name>
        </author>
        <category label="Meetups" term="Meetups"/>
        <category label="developer.overheid.nl" term="developer.overheid.nl"/>
        <category label="Open Source" term="Open Source"/>
        <category label="Artificial Intelligence" term="Artificial Intelligence"/>
        <category label="Cio" term="Cio"/>
        <category label="Digitale soevereiniteit" term="Digitale soevereiniteit"/>
        <category label="Informatiebeveiliging" term="Informatiebeveiliging"/>
        <category label="Community" term="Community"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[AsyncAPI + CloudEvents; implementatie van asynchrone oplossingen]]></title>
        <id>https://developer.overheid.nl/blog/2026/06/30/asyncapi-3-implementatie-met-cloudevents</id>
        <link href="https://developer.overheid.nl/blog/2026/06/30/asyncapi-3-implementatie-met-cloudevents"/>
        <updated>2026-06-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[In deze laatste blogpost in een reeks van drie wordt een voorzichtige blik 
vooruit geworpen op de implementatie van AsyncAPI. Daarin lijkt het gebruik 
van CloudEvents een logische stap te zijn. Op hoogover niveau wordt er 
gekeken naar de vragen welke gaten in AsyncAPI worden opgevuld CloudEvents,
en wat het oplevert om die twee samen te gaan gebruiken.
]]></summary>
        <content type="html"><![CDATA[<p>In de voorgaande blogposts hebben we gekeken naar wat
<a href="https://www.asyncapi.com/en" target="_blank" rel="noopener noreferrer" class="">AsyncAPI</a> is, hoe het zich in de praktijk gedraagt
en in welke situaties het daadwerkelijk waarde toevoegt (of juist niet). Daarmee
staat er een grove leidraad voor wanneer AsyncAPI te implementeren, en is de
kernvraag van de werkgroep in zekere mate beantwoord. Dit is natuurlijk niet
voldoende. Los van dat de kernvraag van de werkgroep nog een lopende discussie
is lijkt het logische vervolg om te gaan kijken naar hoe dit alles daadwerkelijk
geïmplementeerd kan/moet worden. In deze blogpost heb ik gepoogd om vast een
stukje vooruit te kijken, met als kern de vraag: hoe zorg je ervoor dat events
niet alleen goed beschreven zijn, maar ook consistent en interoperabel worden
uitgewisseld tussen systemen?</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>Na een wat theoretische behandeling van AsyncAPI is het tijd om naar de toekomst
te kijken. Cloudevents, een aangenomen standaard binnen de Nederlandse Overheid,
vult AsyncAPI aan in het beschrijven van events en het implementeren van Event Driven
Architecture. Het doet dit door concreet in te vullen hoe asynchrone berichten eruit
zien, waar AsyncAPI alleen beschrijft wat voor soort berichten er verstuurd worden
en waar dat verkeer leeft. Met Cloudevents en AsyncAPI samen volgt er documentatie
waar vervolgens met gemak op te ontwikkelen en implementeren valt. De werkgroep
AsyncAPI gaat zich richten op dit alles verder uitwerken; wie mee wil doen met de
discussie is meer dan welkom om aan te schuiven!</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="cloudevents">CloudEvents<a href="https://developer.overheid.nl/blog/2026/06/30/asyncapi-3-implementatie-met-cloudevents#cloudevents" class="hash-link" aria-label="Direct link naar CloudEvents" title="Direct link naar CloudEvents" translate="no">​</a></h2>
<p>Waar AsyncAPI zich richt op het beschrijven van berichtenstromen, biedt het niet
een gestandaardiseerde manier om events zelf vorm te geven. Het documenteert wel
wat er voor berichten over de lijn gaan, maar het definieert geen uniforme set
metadata, zoals type, bron, identificatie of tijdstip, die losstaat van de
inhoud van het bericht. Daarmee ontstaat een scheiding tussen wat een event is
en wat een event bevat. Deze scheiding onderkennen is één ding, hem goed kunnen
beschrijven is een tweede, en dit is waar CloudEvents om de hoek komt kijken.</p>
<p>In een
<a href="https://developer.overheid.nl/blog/2026/03/06/event-driven" target="_blank" rel="noopener noreferrer" class="">eerdere blogpost</a>
is al uitgebreid over CloudEvents gesproken in de context van Event-Driven
Architecture. Zie al wat volgt dan ook vooral als een vervolg op de AsyncAPI
mention die daar kort in voorkomt, en als een manier om de zaken uit de vorige
twee posts in deze reeks van een theoretische realisatie te voorzien.</p>
<p>Laat ik dan ook teruggrijpen naar een eerdere observatie: AsyncAPI maakt
expliciet wat er over de lijn gaat, maar laat veel ruimte in hoe dat er concreet
uitziet. Die flexibiliteit is krachtig en tevens deel van wat de specificatie zo
aantrekkelijk maakt, maar kan ook leiden tot variatie waar je die misschien niet
wil hebben. Twee teams kunnen hetzelfde soort event modelleren, maar toch
verschillende keuzes maken in metadata, naamgeving of contextinformatie. Binnen
één team of tussen twee nauw-verbonden teams is dat vaak nog te overzien, maar
op grotere schaal zal dit geheid uitlopen op problemen.</p>
<p><a href="https://cloudevents.io/" target="_blank" rel="noopener noreferrer" class="">CloudEvents</a> vangt precies dat probleem af door een
minimale, duidelijke standaard neer te zetten voor event-metadata en het
beschrijven/definiëren van het event zelf. Opgenomen als
<a class="" href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/cloudevents">NL GOV profiel</a> en door
<a href="https://www.forumstandaardisatie.nl/open-standaarden/nl-gov-profile-CloudEvents" target="_blank" rel="noopener noreferrer" class="">Forum Standaardisatie</a>
op de “pas toe, leg uit” lijst gezet, CloudEvents specifieert onder andere
uniforme naamgeving en metadata, afspraken over payloads en headers, notificatie
toepassingen van de overheid en meer. Dit is precies wat AsyncAPI open laat.
Door CloudEvents als standaard te combineren met AsyncAPI ontstaat een gelaagd
model: AsyncAPI beschrijft de structuur, het gedrag en de context van
berichtenstromen, terwijl CloudEvents zorgt voor een consistente “envelop”
waarin die berichten worden verstuurd. Het resultaat is een combinatie waarin
zowel documentatie als implementatie beter op elkaar aansluiten.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="toepasgebied">Toepasgebied<a href="https://developer.overheid.nl/blog/2026/06/30/asyncapi-3-implementatie-met-cloudevents#toepasgebied" class="hash-link" aria-label="Direct link naar Toepasgebied" title="Direct link naar Toepasgebied" translate="no">​</a></h2>
<p>Wanneer zou dit nou echt tot zijn recht komen? Los van alle use-cases die in
eerdere posts besproken zijn kijk ik hier vooral naar situaties waarin
interoperabiliteit een belangrijke rol speelt. Binnen de Nederlandse overheid is
het koppelen met systemen van andere organisaties, of zelfs andere teams en
omgevingen binnen de eigen organisatie aan de orde van de dag. Systemen van
verschillende organisaties moeten met elkaar communiceren, vaak zonder dat er
sprake is van directe afstemming of gezamenlijke ontwikkeling. Teams binnen
grote landelijke organisaties lopen er ook tegenaan dat ze afhankelijk zijn van
de events die de wereld in gaan vanuit teams waar ze nooit direct mee in
aanraking komen. In zulke omgevingen is het niet voldoende dat iedereen
“ongeveer hetzelfde” doet; consistentie en voorspelbaarheid zijn randvoorwaarden
voor een goede dienstverlening.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="notificaties">Notificaties<a href="https://developer.overheid.nl/blog/2026/06/30/asyncapi-3-implementatie-met-cloudevents#notificaties" class="hash-link" aria-label="Direct link naar Notificaties" title="Direct link naar Notificaties" translate="no">​</a></h3>
<p>Een concreet voorbeeld hiervan is het uitwisselen van notificaties tussen
ketenpartners. Wanneer een gebeurtenis plaatsvindt, bijvoorbeeld een wijziging
in een registratie of de afronding van een processtap, kan die informatie
relevant zijn voor meerdere afnemers. Denk aan de notificatie dat er iets in de
kadastrale gegevens van een huizenblok gewijzigd gaat worden. Door zo’n
gebeurtenis als CloudEvent te versturen, voorzien van gestandaardiseerde
metadata en opgesteld volgens een NLgov standaard wordt het voor afnemers
eenvoudiger om events te routeren, filteren en verwerken. Ontwikkelaars en
architecten hoeven niet te wachten of te gissen naar hoe events eruit zien en
wat voor soorten gegevens erin komen te staan; ze kunnen het gewoon opzoeken en
afvangen. AsyncAPI kan in deze context gebruikt worden om vast te leggen welke
events bestaan, hoe de payload eruitziet en welke semantiek eraan verbonden is.
Daarmee heb je de combinatie te pakken van “wat is er allemaal” en “hoe ziet het
eruit”; oftewel, vorm en inhoud van de communicatie worden hiermee helder.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="cross-team-integraties">Cross-team integraties<a href="https://developer.overheid.nl/blog/2026/06/30/asyncapi-3-implementatie-met-cloudevents#cross-team-integraties" class="hash-link" aria-label="Direct link naar Cross-team integraties" title="Direct link naar Cross-team integraties" translate="no">​</a></h3>
<p>Een ander scenario waarin deze combinatie waarde toevoegt, is dat van cross-team
en cross-organisatie integraties. Denk aan het moment dat een team van de
Politie een event van een ander team binnen de Politie wil afnemen, of dat een
team bij de KMar datzelfde event ook ergens voor nodig heeft. Zoals eerder
beschreven ontstaat daar vaak een situatie waarin overzicht op de volledige
keten makkelijk te verliezen is, met als gevolg dat er meerdere waarheden gaan
ontstaan. Door CloudEvents te gebruiken als gemeenschappelijke basis voor
event-metadata, kunnen teams onafhankelijk van elkaar werken zonder dat ze
telkens opnieuw afspraken moeten maken over basiselementen zoals identificatie
of herkomst. AsyncAPI fungeert daarbij als de plek waar die events formeel
worden beschreven en gedeeld. Dit ondersteunt het idee van een “single source of
truth”, zonder dat het de autonomie van individuele teams beperkt.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="auditing-en-replay">Auditing en replay<a href="https://developer.overheid.nl/blog/2026/06/30/asyncapi-3-implementatie-met-cloudevents#auditing-en-replay" class="hash-link" aria-label="Direct link naar Auditing en replay" title="Direct link naar Auditing en replay" translate="no">​</a></h3>
<p>Ook in meer technische use cases, zoals auditing of event replay, biedt de
combinatie duidelijke voordelen. CloudEvents schrijft bijvoorbeeld voor dat elk
event een unieke identifier en timestamp bevat. Dat lijkt een detail, maar maakt
het aanzienlijk eenvoudiger om events later opnieuw te verwerken of te
analyseren. Voor organisaties die willen voldoen aan de transparantie principes
die ten grondslag liggen aan zaken als Wet Open Overheid is het goed na kunnen
gaan en aan kunnen tonen wat er met data gebeurt, wie wat initieert en waar
gegevens naartoe gaan van cruciaal belang. In combinatie met het relatief
makkelijke versiebeheer in AsyncAPI ontstaat zo een robuuste basis voor het
omgaan met historische data, zelfs wanneer schema’s in de loop der tijd
veranderen. Kortom, in het kader van auditing en transparantie is dit alles
zeker geen overbodige luxe binnen een complex bolwerk als de gehele Nederlandse
overheid.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="hoe-dit-aan-te-pakken">Hoe dit aan te pakken?<a href="https://developer.overheid.nl/blog/2026/06/30/asyncapi-3-implementatie-met-cloudevents#hoe-dit-aan-te-pakken" class="hash-link" aria-label="Direct link naar Hoe dit aan te pakken?" title="Direct link naar Hoe dit aan te pakken?" translate="no">​</a></h2>
<p>De vraag is dan hoe een implementatie van deze combinatie er in de praktijk uit
zou gaan zien. In de basis begint het met het vaststellen van een aantal
afspraken op organisatieniveau. AsyncAPI alleen bleek al baat te hebben bij
duidelijke keuzes rondom naamgeving, perspectief en tooling; met CloudEvents
komt daar een extra laag bij. Denk aan afspraken over welke attributen verplicht
zijn, hoe typen worden benoemd en hoe bronnen worden geïdentificeerd. Zonder die
afspraken bestaat het risico dat de standaard wel wordt gebruikt, maar niet op
een consistente manier. Hier is voor CloudEvents al een NLgov profiel voor
opgesteld en verplicht gesteld (“pas toe, leg uit”). AsyncAPI heeft deze nog
niet, omdat de discussie over het toepassingsgebied nog een lopende zaak is,
maar laten we er t.b.v. het uitdenken van een implementatie er even vanuit gaan
dat een dergelijke duiding wel komt.</p>
<p>Na het opstellen van afspraken en/of “leg uit’s” in de context van “pas toe, leg
uit” komt de modellering zelf. In AsyncAPI wordt vastgelegd welke events
bestaan, via welke Channels ze worden uitgewisseld en hoe de payload is
opgebouwd. Dit is een inhoudelijke klus die kennis van AsyncAPI vereist, maar
ook kennis van de daadwerkelijk te modelleren berichtenstroom. CloudEvents kan
daarin op verschillende manieren worden geïntegreerd, bijvoorbeeld door het als
basis te nemen voor de message-structuur of door expliciet te verwijzen naar de
CloudEvents-specificatie binnen de schema’s. Het belangrijkste is dat duidelijk
wordt gemaakt waar de grens ligt tussen generieke metadata en domeinspecifieke
inhoud.</p>
<p>Dan de technische implementatie. Voor producers betekent dit dat zij
verantwoordelijk zijn voor het correct opbouwen van CloudEvents, inclusief de
verplichte metadata. De exacte manier van implementatie is sterk afhankelijk van
de organisatie, maar in de kern zullen er techneuten aan de slag moeten gaan met
het opstellen van CloudEvents die aansluiten op wat er op hoger niveau is
afgesproken. Tegelijkertijd zullen eventuele consumers hun applicaties moeten
inrichten op de AsyncAPI documentatie en informatie over de CloudEvents van de
producer, in het vertrouwen dat dergelijke metadata altijd aanwezig en
consistent is. Middleware, zoals messaging-platforms of event brokers, kan
vervolgens gebruikmaken van die metadata voor routering, filtering of logging,
zonder dat kennis van de payload nodig is. Een voordeel hiervan is dat het
bijdraagt aan verdere ontkoppeling, omdat infrastructuur en businesslogica
minder van elkaar afhankelijk worden.</p>
<p>Wat de opvallende lezer vast allang heeft gemerkt is dat hier eigenlijk geen
nieuwe concepten worden geïntroduceerd, maar dat er slechts bestaande patronen
explicieter en consistenter worden gemaakt. Veel systemen gebruiken immers al
vormen van metadata in hun berichten; CloudEvents neemt de rol aan om daar
structuur in aan te brengen, en AsyncAPI pakt de rol op om de berichtenstromen
zichtbaar, beheersbaar en overdraagbaar te maken. Juist die combinatie van
standaardisatie en documentatie maakt het mogelijk om event-driven werken op
grotere schaal toe te passen zonder dat het verzandt in maatwerkafspraken.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="kijkje-naar-de-toekomst">Kijkje naar de toekomst<a href="https://developer.overheid.nl/blog/2026/06/30/asyncapi-3-implementatie-met-cloudevents#kijkje-naar-de-toekomst" class="hash-link" aria-label="Direct link naar Kijkje naar de toekomst" title="Direct link naar Kijkje naar de toekomst" translate="no">​</a></h2>
<p>Dit is, in een notendop, hoe een implementatie van CloudEvents met AsyncAPI
eruit zou kunnen zien. Het is natuurlijk een kijk naar de toekomst, en daardoor
zijn concrete voorbeelden binnen de Nederlandse overheid nog niet voorhanden. We
zijn echter
<a href="https://www.asyncapi.com/blog/asyncapi-cloud-events" target="_blank" rel="noopener noreferrer" class="">niet de enigen</a> die de
link tussen deze twee gezien heeft; binnen AsyncAPI is vanaf het begin al waarde
gezien in het combineren van CloudEvents en AsyncAPI.</p>
<p>De kaders die in eerdere posts geschetst zijn blijven overigens in dit alles van
toepassing. In kleine, gesloten systemen zal de meerwaarde beperkt zijn, en kan
de extra complexiteit moeilijk te rechtvaardigen zijn. In grotere, dynamische en
organisatie-overstijgende omgevingen ligt dat anders. Daar kan de combinatie van
AsyncAPI en CloudEvents een belangrijke rol spelen in het realiseren van
consistente, betrouwbare en toekomstbestendige communicatie. Daarmee vormt het
een logische volgende stap voor organisaties die niet alleen hun asynchrone
communicatie willen beschrijven, maar deze ook daadwerkelijk willen
standaardiseren en operationaliseren binnen een bredere event-driven
architectuur.</p>
<p>Met deze reeks aan blogposts heb ik geprobeerd een kijkje te geven in de keuken
van de werkgroep AsyncAPI, en ook vast wat vooruit te lopen op de zaken die daar
nu spelen. Mocht je na dit alles gelezen te hebben denken “dit klinkt
interessant”, “oh maar daar heb ik een interessante use case voor”, of misschien
iets als “maar dat weet ik veel beter”, schroom dan vooral niet om je aan te
melden voor de werkgroep via <a href="mailto:api@geonovum.nl" target="_blank" rel="noopener noreferrer" class="">api@geonovum.nl</a>!</p>]]></content>
        <author>
            <name>Floris Deutekom</name>
        </author>
        <category label="API" term="API"/>
        <category label="API Design" term="API Design"/>
        <category label="Event Driven Architecture (EDA)" term="Event Driven Architecture (EDA)"/>
        <category label="AsyncAPI" term="AsyncAPI"/>
        <category label="CloudEvents" term="CloudEvents"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Volle zaal, scherpe vragen: een terugblik op meetup #2]]></title>
        <id>https://developer.overheid.nl/blog/2026/06/23/meetup-juni</id>
        <link href="https://developer.overheid.nl/blog/2026/06/23/meetup-juni"/>
        <updated>2026-06-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Op woensdag 17 juni organiseerden wij de tweede editie van onze developer.overheid.nl Meetup in Utrecht.
]]></summary>
        <content type="html"><![CDATA[<p>Hij zit er weer op, de tweede editie van onze meetup! Wat een mooie middag: een
volle zaal met developers, scherpe vragen, goede gesprekken en ook nog een
gezellige borrel bij Ruig achteraf. Graag delen we een korte terugblik met je
van de sessies.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span><strong>Datum volgende editie bekend</strong></div><div class="admonitionContent_ZZhP"><p>De volgende meetup zal plaatsvinden op <strong>15 december</strong>. Noteer hem in je agenda
en houd opensourcewerken.nl in de gaten, daar zal het event te zijner tijd
verschijnen.</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="anne-schuth-platform-engineering">Anne Schuth: Platform engineering<a href="https://developer.overheid.nl/blog/2026/06/23/meetup-juni#anne-schuth-platform-engineering" class="hash-link" aria-label="Direct link naar Anne Schuth: Platform engineering" title="Direct link naar Anne Schuth: Platform engineering" translate="no">​</a></h3>
<p>Anne Schuth opende met een prikkelende stelling: de Nederlandse overheid is
misschien wel het grootste softwarebedrijf van Nederland, waarom organiseert ze
zich dan nog niet zo? Hij liet zien hoe platform engineering developers kan
ontlasten, hoe je standaarden by design kunt afdwingen en hoe beleid letterlijk
onderdeel kan worden van je code, inclusief verwijzingen naar wetsartikelen.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Anne Schuth tijdens zijn praatje over platform engineering.&amp;quot;" src="https://developer.overheid.nl/assets/images/anne-6c03d81de5f0f2276aba93fd2e91413b.jpg" width="3000" height="2399" class="img_rVHu">
<em>Anne Schuth tijdens zijn talk over platform engineering.</em></p>
<a class="nl-link rhc-link" href="https://bg.rijks.app/?present=1&amp;slide=1&amp;tour=keten"><p>Naar de demo van Anne</p><span class="utrecht-icon" role="presentation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-arrow-narrow-right"><path d="M5 12l14 0"></path><path d="M15 16l4 -4"></path><path d="M15 8l4 4"></path></svg></span></a>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="dimitri-en-tom-features-live-demo">Dimitri en Tom: features live demo<a href="https://developer.overheid.nl/blog/2026/06/23/meetup-juni#dimitri-en-tom-features-live-demo" class="hash-link" aria-label="Direct link naar Dimitri en Tom: features live demo" title="Direct link naar Dimitri en Tom: features live demo" translate="no">​</a></h3>
<p>Onze collega’s Dimitri van Hees en Tom Ootes lieten aan de hand van een live
demo zien welke verbeteringen aan onze producten er allemaal zijn doorgevoerd.
Dimitri liet zien hoe je een API bouwt met behulp van de
<a href="https://github.com/developer-overheid-nl/skills-developer-overheid-nl" target="_blank" rel="noopener noreferrer" class="">AI-Skills van developer.overheid.nl</a>
en de <a href="https://github.com/developer-overheid-nl/oas-generator/" target="_blank" rel="noopener noreferrer" class="">OAS-generator</a>
tool die direct voldoet aan de API Design Rules. In de tweede fase van de demo
maakte Tom de repository klaar voor open source gebruik. Hij deed dit met behulp
van een bijbehorende
<a href="https://github.com/developer-overheid-nl/skills-repo-docs-generator" target="_blank" rel="noopener noreferrer" class="">AI-Skill</a>
en de
<a href="https://developer-overheid-nl.github.io/repo-docs-generator" target="_blank" rel="noopener noreferrer" class="">repo-docs-generator tool</a>.</p>
<a class="nl-link rhc-link" href="https://github.com/developer-overheid-nl/oas-generator/"><p>OAS Generator</p><span class="utrecht-icon" role="presentation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-arrow-narrow-right"><path d="M5 12l14 0"></path><path d="M15 16l4 -4"></path><path d="M15 8l4 4"></path></svg></span></a>
<br>
<br>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Foto van het koffiemoment.&amp;quot;" src="https://developer.overheid.nl/assets/images/pauze-e6c4060c6d87eb6cc60a8abe82bb7f7e.jpg" width="5712" height="4284" class="img_rVHu">
<em>Foto van het koffiemoment.</em></p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="johan-groenen-codeoverheidnl">Johan Groenen: code.overheid.nl<a href="https://developer.overheid.nl/blog/2026/06/23/meetup-juni#johan-groenen-codeoverheidnl" class="hash-link" aria-label="Direct link naar Johan Groenen: code.overheid.nl" title="Direct link naar Johan Groenen: code.overheid.nl" translate="no">​</a></h3>
<p>Johan Groenen nam ons mee in code.overheid.nl: de nieuwe gedeelde gitomgeving
voor de overheid, gebouwd op Forgejo. Niet alleen een alternatief voor GitHub,
maar vooral een plek waar overheidsdevelopers samen kunnen werken aan open
source software, een stap richting digitale soevereiniteit.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Johan Groenen tijdens zijn praatje over code.overheid.nl.&amp;quot;" src="https://developer.overheid.nl/assets/images/johan-9aa165ee570e3061e029baa5c8e1f981.jpg" width="5712" height="4284" class="img_rVHu">
<em>Johan Groenen tijdens zijn talk over code.overheid.nl.</em></p>
<a class="nl-link rhc-link" href="https://developer.overheid.nl/slides/slides_johan.pdf"><p>Download de slides van Johan</p><span class="utrecht-icon" role="presentation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-arrow-narrow-right"><path d="M5 12l14 0"></path><path d="M15 16l4 -4"></path><path d="M15 8l4 4"></path></svg></span></a>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="jan-klopper-openkat">Jan Klopper: OpenKAT<a href="https://developer.overheid.nl/blog/2026/06/23/meetup-juni#jan-klopper-openkat" class="hash-link" aria-label="Direct link naar Jan Klopper: OpenKAT" title="Direct link naar Jan Klopper: OpenKAT" translate="no">​</a></h3>
<p>Jan Klopper liet zien wat OpenKAT mogelijk maakt: een open source securitytool,
ontstaan bij VWS tijdens de coronacrisis en inmiddels gedragen door een actieve
community. Met slimme plugins, de zogenoemde boefjes, breng je het
aanvalsoppervlak van je organisatie feitelijk en forensisch geborgd in kaart.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Jan Klopper tijdens zijn praatje over OpenKAT&amp;quot;" src="https://developer.overheid.nl/assets/images/jan-949d1c5b6d0e0863f6ab5dc627e9958e.jpg" width="2775" height="2219" class="img_rVHu">
<em>Jan Klopper tijdens zijn praatje over OpenKAT.</em></p>
<a class="nl-link rhc-link" href="https://openkat.nl/"><p>Meer over OpenKAT</p><span class="utrecht-icon" role="presentation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-arrow-narrow-right"><path d="M5 12l14 0"></path><path d="M15 16l4 -4"></path><path d="M15 8l4 4"></path></svg></span></a>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="vervolg">Vervolg<a href="https://developer.overheid.nl/blog/2026/06/23/meetup-juni#vervolg" class="hash-link" aria-label="Direct link naar Vervolg" title="Direct link naar Vervolg" translate="no">​</a></h2>
<p>Wil je zelf aan de slag? Er volgen workshops waarin we dieper ingaan op de
tools, standaarden en toepassingen die tijdens de middag voorbij kwamen. Houd
hiervoor onze website in de gaten.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="zet-in-je-agenda">Zet in je agenda<a href="https://developer.overheid.nl/blog/2026/06/23/meetup-juni#zet-in-je-agenda" class="hash-link" aria-label="Direct link naar Zet in je agenda" title="Direct link naar Zet in je agenda" translate="no">​</a></h2>
<p>Belangrijk nieuws: de datum voor de volgende editie is ook al bekend. Dat zal
namelijk <strong>15 december</strong> zijn. Noteer hem in je agenda en houd
opensourcewerken.nl in de gaten, daar zal het event tzt verschijnen.</p>
<p>Verder willen we graag alle sprekers en developers bedanken voor hun bijdragen,
vragen en ideeën. Tot de volgende keer!</p>]]></content>
        <author>
            <name>Tom Ootes</name>
        </author>
        <category label="Meetups" term="Meetups"/>
        <category label="developer.overheid.nl" term="developer.overheid.nl"/>
        <category label="Open Source" term="Open Source"/>
        <category label="Artificial Intelligence" term="Artificial Intelligence"/>
        <category label="API Design Rules" term="API Design Rules"/>
        <category label="OpenAPI Specification" term="OpenAPI Specification"/>
        <category label="Forgejo" term="Forgejo"/>
        <category label="Digitale soevereiniteit" term="Digitale soevereiniteit"/>
        <category label="Informatiebeveiliging" term="Informatiebeveiliging"/>
        <category label="Community" term="Community"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Wij waren op FOST 2026: een terugblik]]></title>
        <id>https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026</id>
        <link href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026"/>
        <updated>2026-06-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Twee dagen stonden wij op FOST Amsterdam met onze NL Gov-track: een API-track en een open source-track. Een terugblik op de talks.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="&amp;quot;Frank Terpstra tijdens de plenaire opening.&amp;quot;" src="https://developer.overheid.nl/assets/images/frank-15f9579eb883dd3c1d7b266c61d3fd5c.jpg" width="900" height="619" class="img_rVHu"> <em>Frank
Terpstra opende de API-track plenair.</em></p>
<p>Op 9 en 10 juni stonden wij twee dagen op
<a href="https://www.futureofsoftwaretechnologies.com/" target="_blank" rel="noopener noreferrer" class="">FOST</a> Amsterdam met onze eigen
NL Gov-track. FOST (<em>Future of Software Technologies</em>) begon ooit als de
wereldbekende <a href="https://www.apidays.global/" target="_blank" rel="noopener noreferrer" class="">API Days</a>-conferentie, maar groeide
uit tot een wereldwijd paraplu-event waaronder verschillende miniconferenties
vallen; oprichter Mehdi Medjaoui maakte gekscherend de vergelijking van monoliet
naar microservices. Naast API Days zelf vallen daar onder meer de conferenties
van <a href="https://www.openapis.org/" target="_blank" rel="noopener noreferrer" class="">OpenAPI</a>,
<a href="https://json-schema.org/" target="_blank" rel="noopener noreferrer" class="">JSON Schema</a>, <a href="https://www.asyncapi.com/" target="_blank" rel="noopener noreferrer" class="">AsyncAPI</a>,
<a href="https://greenio.tech/" target="_blank" rel="noopener noreferrer" class="">Green IO</a> en deze editie dus ook wijzelf onder. Ons
goedbezochte event bestond uit twee onderdelen: een API-track en een open
source-track. Van ons eigen developer.overheid.nl-team betraden Dimitri, Tom,
Frank, Floris en Joost het podium, samen met andere collega's uit binnen- en
buitenland. Een terugblik op twee inspirerende dagen.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="api-track">API-track<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#api-track" class="hash-link" aria-label="Direct link naar API-track" title="Direct link naar API-track" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="nationale-api-strategie-en-governance">Nationale API-strategie en governance<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#nationale-api-strategie-en-governance" class="hash-link" aria-label="Direct link naar Nationale API-strategie en governance" title="Direct link naar Nationale API-strategie en governance" translate="no">​</a></h3>
<p>Hoe bouw je een nationale API-strategie, en hoe krijg je organisaties mee zonder
ze te dwingen? Die vraag liep als een rode draad door meerdere talks.</p>
<p>Dimitri van Hees blikte terug op acht jaar
<a href="https://developer.overheid.nl/" target="_blank" rel="noopener noreferrer" class="">developer.overheid.nl</a>. Het ontstond tijdens een
bijeenkomst van de Europese Commissie in Italië, bedoeld om API-kennis tussen
lidstaten uit te wisselen. Hier was Nederland het enige land dat met meer dan
één organisatie aanwezig was; zowel Kadaster, CBS, BZK en de gemeente Amsterdam
waren onafhankelijk van elkaar uitgenodigd om, bij gebrek aan een centrale
IT-organisatie, de Nederlandse digitale overheid te vertegenwoordigen. Op
diezelfde bijeenkomst ontmoetten ze Roberto Polli, wiens team toen al ver was
met een eigen developer portal; developer.overheid.nl is mede op dat voorbeeld
gebaseerd. Wat begon als een simpele lijst van overheids-API's, is inmiddels een
kennisbank voor zowel consumenten als aanbieders. Omdat een formeel mandaat
ontbreekt, werkt het platform via waarde toevoegen: vindbaarheid, gratis
validatietools en beveiligingsscans. Het API-register accepteert alleen API's
met een OpenAPI-specificatie, kent scores toe op basis van de API Design Rules
en ondersteunt lifecyclemanagement. Recent toegevoegd: een Open Source Register
op basis van <code>publiccode.yml</code>, notificaties via RSS en Slack, en experimenten
met AI Agent Skills.</p>
<p>Roberto Polli, voorheen van het <em>Dipartimento per la Trasformazione Digitale</em>,
was mede-verantwoordelijk voor de totstandkoming van de
<a href="https://developers.italia.it/" target="_blank" rel="noopener noreferrer" class="">Italiaanse developer portal</a> en API-strategie,
precies het register dat Dimitri als inspiratie noemde. In een van zijn twee
talks liet hij zien hoe die strategie tot stand kwam. Het oude SOAP-framework
werkte prima voor grote instanties, maar met opstartkosten van zo'n 200.000 euro
was het onbetaalbaar voor de meer dan 8.000 kleine gemeenten. De overstap naar
een REST-vriendelijk framework was dus een kwestie van toegankelijkheid. De
lockdown van 2020 maakte de urgentie zichtbaar, en daarna volgde een API Cloud
waarin instanties verplicht hun API's publiceren en handmatige overeenkomsten
zijn vervangen door digitale delegatie. Zijn vier randvoorwaarden voor succes:
politiek commitment, technische expertise in de uitvoering, betrokkenheid bij
internationale standaardisatie, en juristen die in het team zitten in plaats van
op een aparte afdeling.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Roberto Polli.&amp;quot;" src="https://developer.overheid.nl/assets/images/roberto-0cad2e383454cd4a065fb9015de4c60a.jpg" width="1600" height="940" class="img_rVHu"> <em>Roberto Polli sprak over de Italiaanse
API-strategie.</em></p>
<p>Frank Terpstra, die al jaren aan de Nederlandse API-strategie werkt, ging in een
panel in gesprek met Dimitri en Janette Storm (Kadaster). Daar kwam het
spanningsveld scherp naar voren: je moet een standaard eerst laten werken
voordat je die verplicht stelt. Een "wall of shame" werkt averechts, want wie
niet voldoet laat zich liever van de lijst halen dan zich aanpassen. Ook bleek
dat je per doelgroep een andere taal moet spreken: beleidsmakers zoeken
kostenbesparing, productmanagers willen klantcontact verbeteren en developers
kijken naar concrete Design Rules en tooling. Mooie observatie: API's worden
steeds vaker ingezet om het datakopieerprobleem bespreekbaar te maken bij
bestuurders, een thema dat de krantenkoppen haalt. Tot slot klonk de roep om
meer Europese coördinatie.</p>
<p>Tim van der Lippe (Logius) presenteerde de NLgov REST API Design Rules. Elke
regel is gebaseerd op echte beslissingen van overheidsorganisaties waarvan
inmiddels bekend is of ze goed of slecht uitpakten. Door de standaard, het
API-register en analyses van API's in het wild samen te brengen, ontstaat een
levende standaard die gevoed wordt door wat developers daadwerkelijk bouwen.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="schemas-en-semantische-interoperabiliteit">Schemas en semantische interoperabiliteit<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#schemas-en-semantische-interoperabiliteit" class="hash-link" aria-label="Direct link naar Schemas en semantische interoperabiliteit" title="Direct link naar Schemas en semantische interoperabiliteit" translate="no">​</a></h3>
<p>Verschillende organisaties beschrijven dezelfde entiteit vaak op totaal
verschillende manieren. Vier sprekers lieten zien hoe je daar met schemas en
semantiek grip op krijgt. Over dit thema verschijnt binnenkort een aparte en
uitgebreidere blogpost.</p>
<p>Tom Collins werkt voor de
<a href="https://www.gov.uk/government/organisations/driver-and-vehicle-licensing-agency" target="_blank" rel="noopener noreferrer" class="">DVLA</a>,
de Britse instantie voor rijbewijzen en voertuigen, en beheert gegevens over
zo'n vijftig miljoen voertuigen. Zijn oplossing voor teams die in silo's
dezelfde begrippen anders definiëren, is het Schema Dictionary: een centraal
Git-repository op basis van JSON Schema. De werkwijze is schema-first, het
datamodel wordt via peer-reviews beoordeeld voordat er code is, en vanuit de
centrale schema's worden automatisch code, documentatie, OpenAPI-contracten en
testdata gegenereerd. Inmiddels gebruiken zo'n 450 repositories het systeem; bij
het medische rijbewijsverlengingsproces, dat zes productteams overspant, steeg
het percentage klanten dat het volledig digitaal kon doorlopen van 15 naar 100
procent. Ook hier gold "carrot rather than the stick". De aanpak is bewust puur
structureel: de standaardisatie zit in de schema's zelf, zonder semantische laag
eroverheen.</p>
<p>Dimitri constateerde dat overheids-API's veel meer delen dan ze hergebruiken.
Geïnspireerd door het Schema Dictionary van de DVLA bouwt developer.overheid.nl
daarom zelf aan een nationaal schema-register dat herbruikbare
OpenAPI-componenten en JSON Schemas beschikbaar stelt als bouwstenen, met
bijbehorende schema-ontwerpregels. Hij liet ook zien hoe zijn team eigen tooling
en AI-hulpmiddelen inzet om een complete OpenAPI 3.1-specificatie met ingebedde
JSON Schemas te genereren en valideren.</p>
<p>Ingo Simonis (<a href="https://www.ogc.org/" target="_blank" rel="noopener noreferrer" class="">Open Geospatial Consortium</a>) draaide het
perspectief om: niet de hoeveelheid data telt, maar de betekenis ervan. Een
AI-agent faalt niet omdat hij data niet kan bereiken, maar omdat hij die niet
betrouwbaar kan interpreteren. Niet-gedeclareerde eenheden, lokale categorieën
en impliciete referentiesystemen zijn stuk voor stuk uitnodigingen om te raden,
en raden op de semantische laag is waar hallucinaties ontstaan. Zijn stelling:
organisaties die de AI-decade winnen, behandelen expliciete kennis als
infrastructuur, niet als documentatie. De semantische gemeenschap lost dit
probleem al dertig jaar op, merkte hij droog op, en de rest van de wereld
arriveert nu pas aan de deur.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Ingo Simonis.&amp;quot;" src="https://developer.overheid.nl/assets/images/ingo-048650c9a7f5265fd498f8ddc88ada05.jpg" width="1200" height="894" class="img_rVHu"> <em>Ingo Simonis betoogde dat semantiek, niet de
hoeveelheid data, bepaalt of AI-agents informatie betrouwbaar interpreteren.</em></p>
<p>Op precies die drempel stond de andere talk van Roberto Polli.
<a href="https://json-ld.org/" target="_blank" rel="noopener noreferrer" class="">JSON-LD</a> bestaat allang; de echte brug zit in iets
kleiners. Door een extensie als <code>x-jsonld-context</code> toe te voegen aan een
OpenAPI-document leg je de link tussen een schema en zijn betekenis direct in de
specificatie, en stapt de schema-first wereld door de deur die Ingo schetste.
Elke data-eigenschap krijgt een URI die de exacte betekenis vastlegt, zodat
Italiaanse data automatisch koppelt aan bijvoorbeeld Finse of Nederlandse
standaarden zonder dat de onderliggende systemen veranderen. In Italië is dit al
verplicht voor de publieke sector, ondersteund door centrale tools als
<a href="https://api.gov.it/" target="_blank" rel="noopener noreferrer" class="">api.gov.it</a> (meer dan 12.000 publieke API's) en
<a href="https://schema.gov.it/" target="_blank" rel="noopener noreferrer" class="">schema.gov.it</a> (met een real-time conformiteitscore).
De boodschap: maak van de standaard een shortcut, dan omarmen developers die
vanzelf. Inmiddels hebben wij vanuit Nederland vervolggesprekken ingepland met
onze Italiaanse en Britse collega's, het OGC en de Stelselcatalogus, om dit
gezamenlijk aan te pakken.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="events-en-notificaties">Events en notificaties<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#events-en-notificaties" class="hash-link" aria-label="Direct link naar Events en notificaties" title="Direct link naar Events en notificaties" translate="no">​</a></h3>
<p>Met de verschuiving naar Event-Driven Architecture groeit de behoefte aan
standaarden voor ontkoppelde berichtstromen. Twee talks gingen hierop in, beide
voortgekomen uit werkgroepen van het Kennisplatform API's.</p>
<p>Floris Deutekom presenteerde de stand van zaken van de AsyncAPI-werkgroep.
AsyncAPI bouwt voort op OAS, is protocol-agnostisch (Kafka, RabbitMQ, HTTP en
meer) en levert out-of-the-box tooling voor validatie, documentatie en
codegeneratie. In twee praktijkgevallen, de Basisregistratie Ondergrond en Track
&amp; Trace van het Ministerie van Justitie, bleken conversietools betrouwbaarder en
sneller dan handmatig werk. AsyncAPI heeft vooral meerwaarde bij ontkoppelde
architecturen, een onbekend aantal consumenten of een-op-veel-communicatie, en
de combinatie met CloudEvents biedt een uniform kader. Floris is over AsyncAPI
een serie blogposts aan het schrijven, en de eerste staat al online.</p>
<a class="nl-link rhc-link" href="https://developer.overheid.nl/blog/authors/floris-deutekom"><p>Lees hier alle posts van Floris over AsyncAPI</p><span class="utrecht-icon" role="presentation" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-arrow-narrow-right"><path d="M5 12l14 0"></path><path d="M15 16l4 -4"></path><path d="M15 8l4 4"></path></svg></span></a>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Floris Deutekom.&amp;quot;" src="https://developer.overheid.nl/assets/images/floris-66e0d280361a4051400d05e00064d71b.jpg" width="1200" height="1026" class="img_rVHu"> <em>Floris Deutekom presenteerde de stand
van zaken van de AsyncAPI-werkgroep.</em></p>
<p>Danny Greefhorst (BZK/ICTU) plaatste notificaties in de context van een
dataspace voor de Nederlandse overheid, waarin dataproviders en consumenten
rechtstreeks met elkaar interacteren op basis van rulebooks, met data bij de
bron als kernprincipe. De voorkeur gaat uit naar informatie-arme notificaties
die naar de bron verwijzen, wat beveiliging en dataminimalisatie bevordert. Van
de drie patronen, polling, directe notificatie en een event broker, is voor de
Nederlandse overheid met potentieel 1.600 organisaties alleen de broker
schaalbaar genoeg. CloudEvents vormt de standaard voor de metadata, inclusief
een Nederlands profiel. De grootste uitdaging ligt overigens niet in de
techniek, maar in de organisatorische bereidheid om events daadwerkelijk te
delen.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="updates-uit-andere-werkgroepen">Updates uit andere werkgroepen<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#updates-uit-andere-werkgroepen" class="hash-link" aria-label="Direct link naar Updates uit andere werkgroepen" title="Direct link naar Updates uit andere werkgroepen" translate="no">​</a></h3>
<p>Naast AsyncAPI en notificaties deelden ook andere werkgroepen van het
Kennisplatform API's hun voortgang.</p>
<p>Joost Farla trekt de nieuwe werkgroep Historie, die zich richt op het omgaan met
bitemporaliteit in API's bij de overgang van Nederlandse registraties van EBMS
en StUF naar moderne REST API's. De meeste API's kennen alleen de staat van nu,
terwijl de werkgroep twee tijdlijnen onderzoekt: geldigheidstijd (wanneer was
iets waar in de werkelijkheid) en transactietijd (wanneer is het vastgelegd). Zo
wordt een vraag mogelijk als: wat was de weersverwachting voor zaterdag, zoals
we die gisteren kenden? De werkgroep verkent oplossingsrichtingen als
append-only in plaats van overschrijven, opvragen op tijdcoördinaten met
parameters als <code>validAt</code> en <code>recordedAt</code>, en idempotentie via idempotency keys.
Er speelt ook een spanning met de AVG, want append-only botst met het recht om
vergeten te worden; een verkende oplossing is crypto-shredding, waarbij niet de
data maar de encryptiesleutel wordt vernietigd. De kernboodschap: historie is
een functionele eis, geen bijproduct. Over dit onderwerp volgt binnenkort een
aparte en uitgebreidere blogpost.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Joost Farla.&amp;quot;" src="https://developer.overheid.nl/assets/images/joost-5e6ad701dc4cc7e442fe4d721664ca72.jpg" width="1600" height="998" class="img_rVHu"> <em>Joost Farla sprak namens de nieuwe werkgroep
Historie over bitemporaliteit in API's.</em></p>
<p>Frank gaf daarnaast een update vanuit de werkgroep rond access control. Binnen
de publieke sector bestaan best practices voor toegangscontrole bij API's, en de
huidige best practice, de module access control van de API Design Rules, is door
de werkgroep herzien. Frank lichtte toe wat er is veranderd en kondigde aan dat
er een publieke consultatie van start gaat. Wie meer wil weten of wil meedenken,
kan via die consultatie bijdragen.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="apis-in-de-praktijk">API's in de praktijk<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#apis-in-de-praktijk" class="hash-link" aria-label="Direct link naar API's in de praktijk" title="Direct link naar API's in de praktijk" translate="no">​</a></h3>
<p>Drie talks lieten zien hoe overheids-API's op grote schaal in de praktijk
werken.</p>
<p>Janette Storm (Kadaster) liet zien hoe de
<a href="https://bag.basisregistraties.overheid.nl/" target="_blank" rel="noopener noreferrer" class="">Basisregistratie Adressen en Gebouwen</a>
(BAG), een van de meest gebruikte dataregistraties van de Nederlandse overheid,
meegroeide met de API-wereld. Vóór 2009 had elke gemeente een eigen
adresregistratie, sindsdien is er één centrale registratie waarvan gemeenten het
onderhoud blijven doen. De eerste BAG API verscheen in 2019 bijna per toeval,
uit een proof-of-concept met linked data, en won meteen de Gouden API-award.
Opvallend was het adoptieprofiel: private partijen als TomTom en Esri stapten
snel over, terwijl overheden langer vasthielden aan XML. De slimste zet was het
oplossen van de puzzel voor de gebruiker: in plaats van losse objecten die je
zelf moet samenvoegen, biedt een kant-en-klaar adreseindpunt nu 90 procent van
het gebruik. Binnenkort volgt een overstap naar de PDOK Locatie API met betere
ondersteuning voor historische data.</p>
<p>Die overstap sluit aan bij het verhaal van John Schaap (Kadaster) over
<a href="https://www.pdok.nl/" target="_blank" rel="noopener noreferrer" class="">PDOK</a> (Publieke Dienstverlening Op de Kaart), het
nationale geodataplatform met meer dan 200 datasets, bijna 300 API's en diensten
en miljoenen requests per dag. De uitdaging: complexe, heterogene geo-data
toegankelijk én bruikbaar maken voor moderne applicaties. Data ontsluiten is
niet genoeg; developers hebben snelle, consistente en intuïtieve API's nodig.
John deelde de ontwerpprincipes achter PDOK's OGC API's en de PDOK Locatie API,
waarmee PDOK evolueerde van traditionele geoservices naar een modern
API-ecosysteem met vector tile-visualisatie en slimme zoekmogelijkheden.</p>
<p>Bart Huijbers (Kadaster) opende ten slotte de motorkap van het
<a href="https://developer.omgevingswet.overheid.nl/" target="_blank" rel="noopener noreferrer" class="">Digitaal Stelsel Omgevingswet</a>
(DSO). Sinds 1 januari 2024 voegt de Omgevingswet tientallen wetten rond
ruimtelijke ordening, milieu, natuur en water samen, en het DSO is de
ICT-ruggengraat daaronder, van publicatie van regelgeving tot vergunningchecks
en vergunningaanvragen. Naar buiten toe is het één portaal, onder de motorkap
een samenspel van componenten die via een reeks API's data uitwisselen. Aan de
hand van concrete use cases liet Bart zien hoe die API's werken en welke
afwegingen daarin zijn gemaakt.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="open-source-track">Open source-track<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#open-source-track" class="hash-link" aria-label="Direct link naar Open source-track" title="Direct link naar Open source-track" translate="no">​</a></h2>
<p>De open source-track stipte uiteenlopende thema's aan, van digitale autonomie en
wetgeving tot publiccode.yml en digitale democratie.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="digitale-autonomie-begint-bij-open-source">Digitale autonomie begint bij open source<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#digitale-autonomie-begint-bij-open-source" class="hash-link" aria-label="Direct link naar Digitale autonomie begint bij open source" title="Direct link naar Digitale autonomie begint bij open source" translate="no">​</a></h3>
<p>Tom Ootes opende de open source-track plenair met een duidelijke boodschap:
digitale autonomie begint bij open source. Een week voor FOST presenteerde
Europa het Tech Sovereignty Package (3 juni 2026), met onder andere de Cloud and
AI Development Act, Chips Act 2.0 en een nieuwe Europese Open Source Strategie.
Centraal staat het begrip digitale commons: code en infrastructuur die
collectief geproduceerd worden, vrij toegankelijk zijn en in het publiek belang
onderhouden worden, terwijl Europees open source-werk nu nog onevenredig wordt
uitgebuit door grote niet-Europese techbedrijven. Voor de Nederlandse overheid
betekent dat technische volwassenheid: zelf open source kunnen bouwen, hosten en
onderhouden, met platform-engineering als cultuur en samenwerking als norm via
gedeelde design-systems, code.overheid.nl en gedeelde Kubernetes-clusters. Over
AI was Tom scherp: LLM's en agentic AI helpen ons sneller coderen, maar
vibe-coding voor productie keurt hij ten zeerste af en de ethische kant moet nog
worden opgelost. Het goede nieuws: de urgentie en politieke steun zijn er,
OSPO's schieten op binnen de overheid en developers staan te popelen.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Tom Ootes.&amp;quot;" src="https://developer.overheid.nl/assets/images/tom-201ad815bc3804e937fccb4b89ed0f3a.jpg" width="900" height="506" class="img_rVHu"> <em>Tom Ootes opende de open source-track plenair.</em></p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="soevereine-infrastructuur-en-wetgeving">Soevereine infrastructuur en wetgeving<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#soevereine-infrastructuur-en-wetgeving" class="hash-link" aria-label="Direct link naar Soevereine infrastructuur en wetgeving" title="Direct link naar Soevereine infrastructuur en wetgeving" translate="no">​</a></h3>
<p>Marlena van Ooijen (Logius) begon met een tegenstelling: sinds 2020 werkt het
Ministerie van Binnenlandse Zaken aan open source-beleid, maar in de praktijk
gebeurt overheidsontwikkeling nog grotendeels op GitHub. Steeds meer
organisaties delen de overtuiging dat échte open source-samenwerking een
gedeelde, soevereine omgeving vereist. Het antwoord is code.overheid.nl, een
overheidsbrede git-forge op basis van Forgejo, nog in de pilotfase, waarvan de
roadmap samen met de gebruikers wordt uitgewerkt.</p>
<p>August Bournique nam ons mee in de Cyber Resilience Act, de Europese wet die
productveiligheid voor digitale producten, software inbegrepen, reguleert en in
2026 en 2027 gefaseerd in werking treedt. Hij gaf een kijkje achter de schermen
bij het ontwikkelen van de eerste productgerichte softwarestandaarden voor de
CRA. De wet is ambitieus en de implementatie nog onzeker; August lichtte de
tijdlijn toe, en stond stil bij openstaande vraagstukken. Een grote misconceptie
die August graag uit de lucht wilde halen was dat open source-contributers ook
verantwoordelijk kunnen gehouden voor productie-implementaties van hun software,
dit is uitdrukkelijk niet zo.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;August Bournique.&amp;quot;" src="https://developer.overheid.nl/assets/images/august-b9f023bed1c9ae5433725affe4b56982.jpg" width="900" height="675" class="img_rVHu"> <em>August Bournique sprak over de Cyber
Resilience Act.</em></p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="publiccodeyml-als-standaard">publiccode.yml als standaard<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#publiccodeyml-als-standaard" class="hash-link" aria-label="Direct link naar publiccode.yml als standaard" title="Direct link naar publiccode.yml als standaard" translate="no">​</a></h3>
<p>Waar Dimitri eerder inzoomde op het API-register, koos Tom voor de open
source-catalogus, die begin dit jaar volledig <code>publiccode.yml</code>-first is geworden
en inmiddels meer dan 4.000 repositories van de hele Nederlandse overheid telt.
<code>publiccode.yml</code> is een metadatastandaard uit 2018, actief onderhouden door
developers.italia.it en de Europese Commissie. Het is een vlag die je in je
repository plant zodat je project vindbaar wordt, gitforge-agnostisch en
laagdrempelig, met catalogi in Frankrijk, Italië, Duitsland en Nederland. Maar
de standaard schiet nog tekort: hij is ontworpen voor grote, monolithische
applicaties, terwijl het landschap nu draait op REST API's,
cross-organisationele data-uitwisseling en kleinere componenten. Tom riep op om
<code>publiccode.yml</code> toe te voegen aan je repositories, een catalogus op te zetten
en issues in te dienen. Dat is makkelijker geworden, want het team heeft een
AI-skill uitgebracht die het bestand voor je genereert.</p>
<p>Valerio Como (Developer Italia) sloot hier mooi op aan met zijn werk aan de
Public Code Editor, die de Italiaanse overheid gebruikt zodat ook
niet-technische mensen eenvoudig een <code>publiccode.yml</code> kunnen maken. De
uitdagingen waren herkenbaar: onboarding van nieuwe bijdragers, technische
schuld wegwerken, betrouwbaarder releasen en het ontwikkelproces opschalen.</p>
<p><img decoding="async" loading="lazy" alt="&amp;quot;Frank Terpstra en Valerio Como.&amp;quot;" src="https://developer.overheid.nl/assets/images/valerio-a727562927b77ec1b54dbba63e3d9997.jpg" width="900" height="506" class="img_rVHu"> <em>Frank Terpstra en
Valerio Como, die de Public Code Editor van Developer Italia toelichtte.</em></p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="digitale-democratie">Digitale democratie<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#digitale-democratie" class="hash-link" aria-label="Direct link naar Digitale democratie" title="Direct link naar Digitale democratie" translate="no">​</a></h3>
<p>Twee talks gingen over open source-platformen voor digitale democratie.</p>
<p><a href="https://consuldemocracy.org/" target="_blank" rel="noopener noreferrer" class="">Consul Democracy</a>, toegelicht door Lucía
Luzuriaga, ondersteunt participatieprocessen als consultaties, participatief
begroten en gezamenlijk beleid maken, en wordt wereldwijd door overheden
ingezet. Open source maakt transparantie mogelijk, maar brengt ook uitdagingen
mee rond het onderhouden van bijdragen, governance en technische duurzaamheid.
Lucía benadrukte waarom een sterke, internationale civic tech-community
onmisbaar is.</p>
<p>Raoul Kramer vertelde het verhaal achter <a href="https://polisnl.org/" target="_blank" rel="noopener noreferrer" class="">Polis</a>, een open
source participatieplatform dat gelijktijdige digitale discussies tussen
duizenden mensen mogelijk maakt, met stellingen als vertrekpunt. Zijn talk ging
over de weg naar een bruikbare tool: welke ontwerpkeuzes zijn nodig om Polis
geschikt te maken voor de Nederlandse overheid? Aan het einde deelde hij het
blijde nieuws dat Polis onder een nieuwe internationale samenwerking verdergaat:
<a href="https://www.voxit.org/" target="_blank" rel="noopener noreferrer" class="">Voxit</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="open-source-beheer-in-de-praktijk">Open source-beheer in de praktijk<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#open-source-beheer-in-de-praktijk" class="hash-link" aria-label="Direct link naar Open source-beheer in de praktijk" title="Direct link naar Open source-beheer in de praktijk" translate="no">​</a></h3>
<p>Tot slot bracht Thomas Steenbergen (<a href="https://ossyn.com/" target="_blank" rel="noopener noreferrer" class="">OSSYN</a>) zijn OSS Review
Toolkit (ORT) voor het voetlicht. Het opzetten van open source-beheerprocessen
is complex, met tientallen programmeertalen, build-tools en afleveringsmethoden,
en commerciële tools sluiten zelden goed aan op wat Open Source Program Offices
nodig hebben. Meerdere OSPO's bouwden daarom samen ORT. Thomas demonstreerde hoe
het een volledige FOSS-review doorloopt: van het scannen van broncode op
componenten, licenties en kwetsbaarheden, via het oplossen van issues, tot het
genereren van attributiedocumenten en CycloneDX- en SPDX-SBOMs. Wie FOSS-beleid
wil automatiseren via Policy as Code en reviewtijd wil besparen, heeft er een
kant-en-klare oplossing aan.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="tot-slot">Tot slot<a href="https://developer.overheid.nl/blog/2026/06/16/fost-amsterdam-2026#tot-slot" class="hash-link" aria-label="Direct link naar Tot slot" title="Direct link naar Tot slot" translate="no">​</a></h2>
<p>Twee dagen FOST leverden een rijk palet aan inzichten op, van nationale
strategieën en schemas tot digitale autonomie en democratie. Wat ons betreft was
de rode draad helder: standaarden werken het best als ze het makkelijker maken
om het goed te doen dan om het fout te doen. We kijken terug op een geslaagde
editie en danken alle sprekers. Houd onze blog in de gaten voor de
aangekondigde, uitgebreidere posts over schemas en bitemporaliteit!</p>]]></content>
        <author>
            <name>Tom Ootes</name>
        </author>
        <author>
            <name>Dimitri van Hees</name>
        </author>
        <category label="API" term="API"/>
        <category label="API Design" term="API Design"/>
        <category label="API Design Rules" term="API Design Rules"/>
        <category label="OpenAPI" term="OpenAPI"/>
        <category label="JSON Schema" term="JSON Schema"/>
        <category label="Interoperabiliteit" term="Interoperabiliteit"/>
        <category label="AsyncAPI" term="AsyncAPI"/>
        <category label="Event Driven Architecture (EDA)" term="Event Driven Architecture (EDA)"/>
        <category label="CloudEvents" term="CloudEvents"/>
        <category label="Notificaties" term="Notificaties"/>
        <category label="Open Source" term="Open Source"/>
        <category label="publiccode.yml" term="publiccode.yml"/>
        <category label="Digitale autonomie" term="Digitale autonomie"/>
        <category label="Standaarden" term="Standaarden"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[AsyncAPI: Wanneer wel? Wanneer niet?]]></title>
        <id>https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases</id>
        <link href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases"/>
        <updated>2026-06-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[De grote vraag binnen de werkgroep AsyncAPI is op dit moment in welke
gevallen AsyncAPI nou wel en niet van toegevoegde waarde is. Hoewel 
de exacte details nog ter discussie staan zijn er al wel een aantal 
voorlopige conclusies te trekken. In deze blogpost nemen we je mee 
in deze conclusies en kijken we naar de mitsen en de maren in de 
algemene regels die zich nu vormgeven.
]]></summary>
        <content type="html"><![CDATA[<p>In een <a href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe" target="_blank" rel="noopener noreferrer" class="">eerdere blogpost</a> zijn de eerste bevindingen van de werkgroep
<a href="https://www.asyncapi.com/en" target="_blank" rel="noopener noreferrer" class="">AsyncAPI</a> gedeeld na het uitwerken van een tweetal
use cases waarin asynchrone API’s van <a href="https://www.openapis.org/" target="_blank" rel="noopener noreferrer" class="">OAS</a> naar
AsyncAPI werden omgezet. Daarbij werd duidelijk dat AsyncAPI op zichzelf geen
wondermiddel is, maar vooral een krachtig instrument dat helpt om asynchrone
communicatie inzichtelijk en beheersbaar te maken. De overkoepelende vraag is
nog echter niet behandeld: wanneer gaan we het dan wel, en wanneer niet
gebruiken? In deze blog ga ik dieper in op de situaties waarin AsyncAPI wel
geschikt lijkt, en in welke situaties het van weinig toegevoegde waarde lijkt te
zijn.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>AsyncAPI heeft zich als tooling bewezen op een aantal vlakken, maar is minder
van toegevoegde waarde op anderen. Wanneer het landschap complex, veranderlijk,
grootschalig of ontkoppeld is valt er een hoop te halen uit het gebruik van
AsyncAPI. Echter, wanneer het gaat om simpele integraties, kleine berichten,
low-use omgevingen of gewoon als de organisatie niet de benodigde volwassenheid
heeft om het goed te implementeren dan kan AsyncAPI juist een bottleneck gaan
vormen. De details van al deze punten staan zeker nog ter discussie, maar het is
duidelijk dat er potentie in zit.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="toegevoegde-waarde-van-asyncapi">Toegevoegde waarde van AsyncAPI<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#toegevoegde-waarde-van-asyncapi" class="hash-link" aria-label="Direct link naar Toegevoegde waarde van AsyncAPI" title="Direct link naar Toegevoegde waarde van AsyncAPI" translate="no">​</a></h2>
<p>Daar horen een paar disclaimers bij. Bovenal moet duidelijk zijn dat dit gaat om
een work-in-progress; de discussie over welke use cases passend zijn voor het
gebruik van AsyncAPI is in volle gang. Zie dit dan ook echt als een voorlopige
observatie, en niet als een definitieve aanbeveling. Daarnaast wil ik ook echt
nogmaals iets benoemen dat in de eerdere post ook gedeeld is: niet elke
asynchrone interactie vraagt om een uitgebreide specificatie, en niet elk
systeem wordt beter van extra documentatie en tooling. In plaats van een harde
scheiding op basis van techniek lijkt het nu meer dat het onderscheid gemaakt
wordt door de complexiteit van het landschap, de mate van ontkoppeling en de
dynamiek van verandering. Met die algemene punten gezegd hebbende, laten we gaan
kijken naar hoe de splitsing er op dit moment uit lijkt te zien, te beginnen met
de “happy flow”, de gevallen waarin AsyncAPI aan de orde is en echt iets
toevoegt.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="onbekende-afnemers">Onbekende afnemers<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#onbekende-afnemers" class="hash-link" aria-label="Direct link naar Onbekende afnemers" title="Direct link naar Onbekende afnemers" translate="no">​</a></h3>
<p>Een van de meest kenmerkende situaties waarin dit het geval is, is die waarin je
niet (meer) precies weet wie je afnemers zijn. In traditionele, synchrone API’s
is dat doorgaans helder: een client roept een endpoint aan en verwacht een
antwoord. Die relatie is expliciet en vaak ook beheersbaar. In asynchrone
omgevingen vervaagt dat beeld. Een systeem publiceert een event, maar heeft geen
volledig zicht op wie dat event consumeert, laat staan wat ermee gebeurt. Juist
daar helpt AsyncAPI om een contract neer te zetten dat losstaat van individuele
afnemers. Niet door te beschrijven wie er luistert, maar door vast te leggen wat
er over de lijn gaat en onder welke voorwaarden. Dat lijkt een subtiel verschil,
maar maakt in de praktijk het onderscheid tussen impliciete afhankelijkheden en
expliciete afspraken.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="1-op-n-communicatie">1-op-N communicatie<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#1-op-n-communicatie" class="hash-link" aria-label="Direct link naar 1-op-N communicatie" title="Direct link naar 1-op-N communicatie" translate="no">​</a></h3>
<p>Die dynamiek wordt nog duidelijker in situaties waarin communicatie niet langer
één-op-één is, maar één-op-veel. In OpenAPI wordt in dergelijke gevallen al snel
vereist dat je dit op basis van webhooks oplost, of dat je een grote hoeveelheid
endpoints gaat modelleren (en elke keer weer nieuwe bij moet definiëren als er
iets wijzigt). Er zijn zeker gevallen waarin dit prima is of zelfs de voorkeur
heeft (zie verderop), maar het neemt niet weg dat wanneer de situatie opschaalt
AsyncAPI native ondersteuning biedt voor “1 event -&gt; multiple consumers”; je
hoeft niks te forceren, het is ervoor gemaakt. Een enkel event kan door meerdere
systemen worden opgepakt, ieder met een eigen interpretatie en vervolgactie.
Door die gebeurtenis centraal te beschrijven, ontstaat er een gedeeld
referentiepunt zonder dat je de onderlinge relaties hoeft dicht te timmeren. Het
gevolg is een vorm van ontkoppeling die niet alleen technisch, maar ook
organisatorisch ruimte biedt.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="ontkoppelde-request-response-flows">Ontkoppelde request-response flows<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#ontkoppelde-request-response-flows" class="hash-link" aria-label="Direct link naar Ontkoppelde request-response flows" title="Direct link naar Ontkoppelde request-response flows" translate="no">​</a></h3>
<p>Een derde categorie waarin AsyncAPI zich nadrukkelijk bewijst, is die waarin
timing geen vaste rol speelt. Dit is in wezen de primaire use-case waar AsyncAPI
voor is opgetuigd, namelijk een asynchrone flow. In een request-response model
zit er per definitie een directe relatie tussen vraag en antwoord; de één wacht
op de ander. In asynchrone ketens ligt dat anders. Een event kan worden
gepubliceerd zonder dat er direct een reactie volgt, en eventuele vervolgstappen
kunnen verspreid in de tijd plaatsvinden. Door die loskoppeling expliciet te
maken in de documentatie, voorkom je dat impliciete aannames ontstaan over
volgorde of responstijden. AsyncAPI sluit hier goed op aan en is er ook gewoon
voor gemaakt; het legt de nadruk op het event zelf en niet op de interactie
eromheen.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="complexegrote-landschappen">Complexe/grote landschappen<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#complexegrote-landschappen" class="hash-link" aria-label="Direct link naar Complexe/grote landschappen" title="Direct link naar Complexe/grote landschappen" translate="no">​</a></h3>
<p>Hier zit een meerwaarde in die groter wordt naarmate ketens langer en complexer
worden. In grotere landschappen, waarin meerdere systemen events publiceren en
consumeren en waarin geen enkele partij het volledige overzicht heeft is het
risico sterk aanwezig dat er geen eenduidig overzicht meer beschikbaar is en
afhankelijkheden uit beeld verdwijnen. Kleine wijzigingen kunnen onverwachte
effecten hebben, simpelweg omdat niet duidelijk is wie er allemaal geraakt
wordt. In dat soort omgevingen fungeert AsyncAPI als een soort verkeerskaart:
wellicht niet volledig tot in alle details, maar wel voldoende om inzicht te
geven in de belangrijkste stromen en afhankelijkheden. Het maakt zichtbaar welke
events bestaan, hoe ze zijn opgebouwd en waar mogelijke breekpunten zitten. Dat
helpt teams niet alleen om hun eigen werk beter te begrijpen, maar ook om
bewuster om te gaan met veranderingen.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="veranderlijk-landschap">Veranderlijk landschap<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#veranderlijk-landschap" class="hash-link" aria-label="Direct link naar Veranderlijk landschap" title="Direct link naar Veranderlijk landschap" translate="no">​</a></h3>
<p>Die veranderlijkheid verdient ook de aandacht in deze context. In systemen
waarin berichten regelmatig evolueren, zoals uitbreidingen van payloads, nieuwe
versies van API’s of aanpassingen in structuur, wordt het risico op
misinterpretatie snel groter. Zonder expliciet contract is het dan lastig om te
bepalen wat wel en niet een breaking change is, en waar compatibiliteit
gewaarborgd moet blijven. AsyncAPI biedt hier houvast door schema’s en versies
expliciet vast te leggen, waardoor wijzigingen niet alleen zichtbaar, maar ook
toetsbaar worden. In combinatie met automatiseerbare tooling voor validatie en
codegeneratie ontstaat zo een mechanisme dat helpt om veranderingen
gecontroleerd door te voeren. Door wijzigingen expliciet te maken krijg je grip
op versiebeheer en worden breaking changes zichtbaar in zowel inhoud als
locatie. AsyncAPI’s strakke documentatie van wat een sender/receiver echt nodig
heeft voorkomt eens te meer dat men stilletjes elkaars systemen breekt.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="complexegrote-berichten">Complexe/grote berichten<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#complexegrote-berichten" class="hash-link" aria-label="Direct link naar Complexe/grote berichten" title="Direct link naar Complexe/grote berichten" translate="no">​</a></h3>
<p>Los van alle landschap-eigenschappen is er ook op gebied van de berichten zelf
een reden om AsyncAPI in gebruik te gaan nemen voor asynchrone API documentatie.
Naarmate payloads groter en gelaagder worden, neemt de kans toe dat
verschillende partijen dezelfde data op een andere manier interpreteren. Zeker
in asynchrone communicatie, waar directe feedback ontbreekt, kan dat leiden tot
fouten die pas laat aan het licht komen. Door de structuur en betekenis van
berichten expliciet te documenteren, verklein je die interpretatieruimte.
AsyncAPI dwingt je niet om die stap te zetten, maar faciliteert het wel op een
manier die goed aansluit bij bestaande ontwikkelpraktijken. Ook hierin is de
automatiseerbare tooling van toegevoegde waarde; de beheerlast van het bijhouden
en valideren van alle versies + het opstellen van passende code kan met een druk
op de knop per versie uitgevoerd worden (mits je dit hebt ingericht natuurlijk,
maar dat spreekt voor zich).</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="event-driven-omgevingen">Event-Driven omgevingen<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#event-driven-omgevingen" class="hash-link" aria-label="Direct link naar Event-Driven omgevingen" title="Direct link naar Event-Driven omgevingen" translate="no">​</a></h3>
<p>Al deze kenmerken komen samen in omgevingen waarin
<a href="https://developer.overheid.nl/blog/2026/03/06/event-driven" target="_blank" rel="noopener noreferrer" class="">Event-Driven Architecture</a>
de norm is. Denk aan Kafka, RabbitMQ, PubSub en meer; zodra events fungeren als
primaire vorm van communicatie, en messaging-platform protocollen de
onderliggende infrastructuur vormen, ligt het gebruik van AsyncAPI voor de hand.
Niet omdat het moet, maar omdat het aansluit bij de manier waarop het systeem is
opgebouwd. Het biedt een gemeenschappelijke taal om events te beschrijven, los
van het specifieke protocol of de implementatie, en maakt het mogelijk om
documentatie, tooling en ontwikkeling beter op elkaar af te stemmen in een
specificatie die gemaakt is om deze type zaken te beschrijven.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="oas-als-betere-optie">OAS als betere optie<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#oas-als-betere-optie" class="hash-link" aria-label="Direct link naar OAS als betere optie" title="Direct link naar OAS als betere optie" translate="no">​</a></h2>
<p>Kortom, AsyncAPI biedt een hoop mogelijkheden. Het is echter zeker niet
alomvattend, ongeacht wat er op de <a href="https://www.asyncapi.com/roadmap" target="_blank" rel="noopener noreferrer" class="">Roadmap</a>
pagina staat. Uit onze eigen onderzoeken en use cases is duidelijk gebleken dat
er situaties zijn waarin de toegevoegde waarde beperkt blijft. Om het verschil
goed te duiden wil ik deze ook in enige mate van detail toelichten.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="simpele-integraties-1-op-1-koppelingen">Simpele integraties; 1-op-1 koppelingen<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#simpele-integraties-1-op-1-koppelingen" class="hash-link" aria-label="Direct link naar Simpele integraties; 1-op-1 koppelingen" title="Direct link naar Simpele integraties; 1-op-1 koppelingen" translate="no">​</a></h3>
<p>De eerste en misschien meest voor de hand liggende situatie is die van
eenvoudige, 1-op-1 koppelingen tussen twee systemen. Wanneer zowel de producer
als de consumer bekend en onder controle zijn van hetzelfde team, of wanneer de
lijnen tussen producer en consumer zeer kort zijn is de noodzaak voor een
uitgebreid contract vaak klein. De betrokken partijen hebben direct contact,
wijzigingen kunnen afgestemd worden en de kans op onverwachte afhankelijkheden
is gering. Naast een minimale noodzaak om het wél te doen is er ook een
duidelijke reden om het niet te doen. Het introduceren van een uitgebreide
specificatie en al het werk dat nodig is om dit op te stellen en bij te gaan
houden gaat dan leiden tot extra beheerlast zonder dat daar een concreet
voordeel tegenover staat.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="simpelekleine-berichten">Simpele/kleine berichten<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#simpelekleine-berichten" class="hash-link" aria-label="Direct link naar Simpele/kleine berichten" title="Direct link naar Simpele/kleine berichten" translate="no">​</a></h3>
<p>Een vergelijkbaar beeld ontstaat bij kleine of eenduidige berichten; denk aan
simpele status berichten als een <code>{ "status": "ok" }</code>. Wanneer de inhoud beperkt
is en er weinig ruimte is voor interpretatie, voegt het modelleren van
uitgebreide schema’s weinig toe. Het risico dat AsyncAPI hier probeert te
ondervangen, namelijk misinterpretatie van complexe data in een uitgebreide en
ontkoppelde keten, is simpelweg niet aanwezig. De investering in documentatie en
tooling weegt dan al snel zwaarder dan de potentiële winst. Een goed voorbeeld
hiervan is de situatie bij de RVIG zoals voorgedragen in de werkgroep. Zij
hebben een simpele asynchrone API implementatie en is ook op onderzoek gegaan om
te kijken of AsyncAPI hier een toevoeging kan zijn. Het gaat hier om een heel
klein bericht in een omgeving die niet heel veel verkeer ziet. Hun conclusie was
dat het opbouwen van AsyncAPI documentatie, het definiëren van Operations,
Messages, Channels e.a. niets opleverde wat niet makkelijker met een asynchrone
PubSub-based API in OAS documentatie te behalen viel. Ook liepen ze er tegenaan
dat het definiëren van Channels vragen opwierp waar geen sluitend antwoord op
bleek; richt je een Channel op per gebeurtenistype? Per persoon? Per abonnee? In
alle gevallen ben je eigenlijk enorme bergen aan beheerlast aan het scheppen.
Kortom, AsyncAPI was/is hier niet de uitkomst.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="low-use-omgevingen">Low-use omgevingen<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#low-use-omgevingen" class="hash-link" aria-label="Direct link naar Low-use omgevingen" title="Direct link naar Low-use omgevingen" translate="no">​</a></h3>
<p>Dan een klein maar toch noemenswaardig vervolg op het vorige punt, waarin we
kijken naar de context waarin systemen opereren. In omgevingen waarin berichten
weinig voorkomen of nauwelijks impact hebben, is de noodzaak voor strakke
contracten beperkt. Denk aan je “nice-to-haves”, non-critical events die tevens
zelden voorkomen en waar het de organisatie “niks” kost als het fout gaat of
verkeerd geïnterpreteerd wordt. In zo’n situatie is het zeer aan te raden om
voor een lichtere aanpak te kiezen dan een volledige AsyncAPI straat opbouwen.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="statische-omgevingen">Statische omgevingen<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#statische-omgevingen" class="hash-link" aria-label="Direct link naar Statische omgevingen" title="Direct link naar Statische omgevingen" translate="no">​</a></h3>
<p>In het verlengde daarvan lijkt AsyncAPI ook minder geschikt voor situaties die
weinig tot niet veranderen over tijd. Zonder iteraties, uitbreidingen, nieuwe
versies of in zijn geheel een noodzaak op aanhoudende governance is de
meerwaarde van uitgebreide contractbeschrijving kleiner. Pak daar de toegevoegde
beheerlast bij en je bent net als eerder meer werk aan het doen aan beheer
opstellen dan dat het je uit handen neemt. Hoewel het van toegevoegde waarde kan
zijn om dit wel te doen als de rest van de organisatie alles op deze wijze
documenteert is AsyncAPI waarschijnlijk teveel gevraagd in use cases waarin niks
gaat veranderen. Dan zouden een paar simpele regels documentatie voldoende
kunnen zijn.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="onvolwassen-organisaties">Onvolwassen organisaties<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#onvolwassen-organisaties" class="hash-link" aria-label="Direct link naar Onvolwassen organisaties" title="Direct link naar Onvolwassen organisaties" translate="no">​</a></h3>
<p>Het moet toch ook genoemd worden: misschien wel de meest onderschatte factor is
de organisatie zelf. AsyncAPI veronderstelt een bepaalde mate van volwassenheid
in het omgaan met documentatie en contracten. Als specificaties niet worden
bijgehouden, als er geen duidelijk eigenaarschap is of als afspraken niet worden
nageleefd, verliest de documentatie snel zijn waarde. In het slechtste geval
ontstaat er een situatie waarin de specificatie een verouderd of onjuist beeld
geeft van de werkelijkheid, met alle risico’s van dien. In die zin geldt hier
een eenvoudige maar belangrijke regel: slechte AsyncAPI is erger dan geen
AsyncAPI. Dit geldt uiteraard voor elke standaard, maar het moet toch benoemd
worden dat AsyncAPI hier echt geen uitzondering op is.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="voorlopige-conclusie">Voorlopige conclusie<a href="https://developer.overheid.nl/blog/2026/06/05/asyncapi-2-use-cases#voorlopige-conclusie" class="hash-link" aria-label="Direct link naar Voorlopige conclusie" title="Direct link naar Voorlopige conclusie" translate="no">​</a></h2>
<p>Alles bij elkaar zijn we tot nu toe op een genuanceerd beeld uitgekomen.
AsyncAPI lijkt bijzonder krachtig in complexe, dynamische en ontkoppelde
omgevingen waarin events een centrale rol spelen en waarin meerdere partijen
onafhankelijk van elkaar opereren. In die context helpt het om structuur aan te
brengen, afspraken expliciet te documenteren en veranderingen beheersbaar te
maken. Tegelijkertijd is het geen vanzelfsprekende keuze voor elke vorm van
communicatie, asynchroon of anderszins. Juist door kritisch te kijken naar de
aard van het probleem en de context waarin het zich voordoet, kun je bepalen of
de inzet van AsyncAPI daadwerkelijk bijdraagt aan een betere oplossing. We zijn
nog niet zover, maar het begint er wel op te lijken dat een NL GOV profiel op
den duur van toegevoegde waarde gaat zijn voor deze standaard.</p>
<p>Hopelijk heeft deze uiteenzetting geholpen met wat inzicht verkrijgen in wanneer
AsyncAPI een oplossing kan zijn. Het kan echter goed zijn dat dit nog te
abstract voelt, en dat men graag wil weten hoe een echte implementatie er nou
uit zou komen te zien. Zoals al gezegd is dit alles nog een work-in-progress,
maar dat neemt niet weg dat we vast een beetje vooruit kunnen kijken. In de
laatste blogpost in deze reeks neem ik jullie mee in de combinatie van AsyncAPI
met Cloudevents, om eens een schets te maken van hoe dit alles in zijn werk zou
gaan als we het echt gaan gebruiken.</p>]]></content>
        <author>
            <name>Floris Deutekom</name>
        </author>
        <category label="API" term="API"/>
        <category label="API Design" term="API Design"/>
        <category label="AsyncAPI" term="AsyncAPI"/>
        <category label="Event Driven Architecture (EDA)" term="Event Driven Architecture (EDA)"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[De Stelselcatalogus is vernieuwd]]></title>
        <id>https://developer.overheid.nl/blog/2026/06/03/nieuwe-stelselcatalogus</id>
        <link href="https://developer.overheid.nl/blog/2026/06/03/nieuwe-stelselcatalogus"/>
        <updated>2026-06-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[De vernieuwde Stelselcatalogus is nu live via www.stelselcatalogus.nl! De
omgeving is gebruiksvriendelijker, actueler en beter voorbereid op de toekomst.
Niet alleen de techniek en interface zijn vernieuwd, ook het onderliggende
informatiemodel is verbeterd. Hierdoor kunnen onder meer specifieke relaties
tussen gegevens worden gelegd.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="De Stelselcatalogus is vernieuwd" src="https://developer.overheid.nl/assets/images/nieuwe-stelselcatalogus-99e02d26dd91b029cc07d2226d331478.png" width="1298" height="842" class="img_rVHu"></p>
<p>De vernieuwde Stelselcatalogus is nu live via
<a href="https://stelselcatalogus.nl/" target="_blank" rel="noopener noreferrer" class="">stelselcatalogus.nl</a>! De omgeving is
gebruiksvriendelijker, actueler en beter voorbereid op de toekomst. Niet alleen
de techniek en interface zijn vernieuwd, ook het onderliggende informatiemodel
is verbeterd. Hierdoor kunnen onder meer specifieke relaties tussen gegevens
worden gelegd.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>De vernieuwde <a href="https://stelselcatalogus.nl/" target="_blank" rel="noopener noreferrer" class="">Stelselcatalogus</a> is live. De
technologie is herschreven op basis van moderne webstandaarden, het
informatiemodel is uitgebreid met begrippenkaders en expliciete relaties tussen
gegevens, en de zoekfunctie is verbeterd. De catalogus biedt metadata over
begrippen en informatiemodellen uit basisregistraties zoals BRP, Handelsregister
en BRK.</p><p>Samen met <a href="https://data.overheid.nl/" target="_blank" rel="noopener noreferrer" class="">data.overheid.nl</a> en
<a href="https://developer.overheid.nl/" target="_blank" rel="noopener noreferrer" class="">developer.overheid.nl</a> vormt het de gezamenlijke
ingang tot overheidsdata binnen het Federatief Datastelsel.</p></div></div>
<p>Wie met data werkt voor maatschappelijke vraagstukken, weet hoeveel tijd gaat
zitten in het vinden, verkrijgen en begrijpen van gegevens. Juist daarom zijn
toegankelijke catalogi onmisbaar en is er in het
<a href="https://federatief.datastelsel.nl/" target="_blank" rel="noopener noreferrer" class="">Federatief Datastelsel</a> (FDS) een
catalogusfunctie voorzien.</p>
<p>Met behulp van metadata biedt de Stelselcatalogus inzicht in gegevens, begrippen
en informatiemodellen, en in de relaties daartussen. Dat helpt om bestaande
datasets beter te gebruiken bij analyse en het oplossen van maatschappelijke
vraagstukken.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="wat-is-er-nieuw">Wat is er nieuw?<a href="https://developer.overheid.nl/blog/2026/06/03/nieuwe-stelselcatalogus#wat-is-er-nieuw" class="hash-link" aria-label="Direct link naar Wat is er nieuw?" title="Direct link naar Wat is er nieuw?" translate="no">​</a></h2>
<p>De technologie achter de catalogus is vernieuwd en sluit beter aan op moderne
webstandaarden. De zoekfunctie en interface zijn verbeterd, zodat gebruikers
sneller de juiste informatie vinden. De catalogus bevat nu naast
informatiemodellen ook begrippenkaders. De vernieuwde structuur legt een stevige
basis voor verdere uitbreiding en betere aansluiting op het Federatief
Datastelsel.</p>
<video controls="" preload="metadata" style="width:100%"><source src="https://www.stelselcatalogus.nl/cms/uploads/Explainer_full_v1_81f8560d75.mp4" type="video/mp4"><p>Je browser ondersteunt geen ingesloten video. Je kunt de video ook
<a href="https://www.stelselcatalogus.nl/cms/uploads/Explainer_full_v1_81f8560d75.mp4" target="_blank" rel="noopener noreferrer" class="">downloaden</a>.</p></video>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="onderdeel-van-een-groter-geheel">Onderdeel van een groter geheel<a href="https://developer.overheid.nl/blog/2026/06/03/nieuwe-stelselcatalogus#onderdeel-van-een-groter-geheel" class="hash-link" aria-label="Direct link naar Onderdeel van een groter geheel" title="Direct link naar Onderdeel van een groter geheel" translate="no">​</a></h2>
<p>In de vernieuwde Stelselcatalogus vind je informatie over begrippen en
informatiemodellen. Metadata van datasets en dataservices vind je via
<a href="https://data.overheid.nl/" target="_blank" rel="noopener noreferrer" class="">data.overheid.nl</a> en
<a href="https://developer.overheid.nl/" target="_blank" rel="noopener noreferrer" class="">developer.overheid.nl</a>. Gezamenlijk vormen deze
voorzieningen de ingang tot overheidsdata.</p>
<p>De Stelselcatalogus geeft overzicht in gegevens die binnen de overheid worden
gebruikt, zoals gegevens uit Basisregistratie Personen (BRP), het
Handelsregister en de Basisregistratie Kadaster (BRK). Bij ieder gegeven staat
extra uitleg over betekenis, herkomst en registratie. Dat helpt beleidsmakers,
architecten, data-analisten en uitvoeringsorganisaties om gegevens beter te
begrijpen, te gebruiken en waar mogelijk te hergebruiken.</p>
<p>Zo draagt de vernieuwde Stelselcatalogus bij aan een overheid waarin data beter
vindbaar, begrijpelijk en toepasbaar is. Meer informatie is te vinden op
<a href="https://stelselcatalogus.nl/" target="_blank" rel="noopener noreferrer" class="">stelselcatalogus.nl</a>.</p>
<p>Wij komen graag in contact met onze stakeholders. Via
<a href="mailto:LogiusContactStelselcatalogus@logius.nl" target="_blank" rel="noopener noreferrer" class="">LogiusContactStelselcatalogus@logius.nl</a>
kun je met ons in contact komen.</p>]]></content>
        <author>
            <name>Kees-Jan Westmaas</name>
        </author>
        <category label="Federatief Data Stelsel" term="Federatief Data Stelsel"/>
        <category label="Interoperabiliteit" term="Interoperabiliteit"/>
        <category label="Gegevensuitwisseling" term="Gegevensuitwisseling"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[AsyncAPI: verkenning en eerste bevindingen]]></title>
        <id>https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe</id>
        <link href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe"/>
        <updated>2026-05-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Developer.overheid.nl werkt samen met de werkgroep AsyncAPI aan het 
onderzoeken van deze technologie, om te zien of het een nieuwe standaard 
kan en moet worden voor asynchroon API ontwerp en documentatie. In deze 
blog wordt het proces tot nu toe en de voorlopige bevindingen gedeeld, 
als voorzet voor de grotere vragen waar we mee zitten.
]]></summary>
        <content type="html"><![CDATA[<p>De afgelopen periode hebben we binnen developer.overheid.nl samen met de
Werkgroep AsyncAPI geëxperimenteerd met het toepassen van AsyncAPI in een aantal
concrete casussen. Het doel van deze werkgroep is om te onderzoeken in welke
mate AsyncAPI als nieuwe standaard voor de Nederlandse overheid geaccepteerd
dient te worden. Niet zozeer om vast te stellen of het werkt, maar vooral om te
begrijpen waar het in de praktijk daadwerkelijk waarde toevoegt, en waar het
vooral extra werk introduceert zonder duidelijke meerwaarde. De technische
werkbaarheid van de specificatie is door diverse use cases aangetoond; de vraag
wanneer we het zouden moeten gebruiken is op dit moment dé kernvraag. Ik wil
jullie in een reeks aan blogposts graag meenemen in waar de werkgroep nu staat
m.b.t. AsyncAPI en hoe we de toekomst voor ons zien.</p>
<p>Om dit alles te gaan bevatten is door de werkgroep eerst aangenomen om wat use
cases te gaan aanpakken en gewoon te zien waar we tegenaan lopen wanneer
AsyncAPI als standaard as-is wordt gebruikt. Hiermee konden we tegelijk
technische affiniteit opdoen, iets van waarde opleveren voor partijen die
daadwerkelijk asynchrone API’s ontsluiten, en informatie verzamelen voor het
beantwoorden van de grote vraag: “moet dit een nieuwe standaard worden as-is, of
is er een NLGov profiel nodig?” Met dit in het achterhoofd is een tweetal cases
opgepakt en zijn we de diepte ingedoken, met regelmatige besprekingen in de
werkgroep.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>De Werkgroep AsyncAPI heeft concrete cases uitgewerkt om te toetsen of AsyncAPI
een standaard moet worden voor de Nederlandse overheid. De technische werking is
bewezen: conversie van bestaande API-documentatie is goed te doen en de tooling
is volwassen. Maar AsyncAPI voegt pas écht waarde toe in een volwaardig
Event-Driven landschap, niet bij een simpele 1-op-1 conversie van bestaande
OpenAPI-specs. De kern­vraag: moet de standaard as-is worden opgenomen of met
een NLGov-profiel. Deze vraag staat nog open en komt in volgende blogposts aan
bod.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="asyncapi">AsyncAPI<a href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe#asyncapi" class="hash-link" aria-label="Direct link naar AsyncAPI" title="Direct link naar AsyncAPI" translate="no">​</a></h2>
<p>Maar eerst even wat achtergrond en introductie voor wie nog niet bekend is met
AsyncAPI. In het kort, AsyncAPI is een open source set aan standaarden en tools
voor ontwikkelen en documenteren van asynchrone API’s en
<a href="https://developer.overheid.nl/blog/2026/03/06/event-driven" target="_blank" rel="noopener noreferrer" class="">Event-Driven Architecture</a>
in zijn algemeen. Het is tevens een voortborduursel op het werk van
<a href="https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/openapi-specification/" target="_blank" rel="noopener noreferrer" class="">OpenAPI Initiative</a>,
waarin door een toegewijd team van experts wordt gepoogd om een nieuwe standaard
te bouwen voor asynchrone API’s binnen de context van Event-Driven Architecture.
AsyncAPI is hierin geen runtime tool, het is voor documentatie, contract en
standaardisatie voor Event-Driven systemen. Het helpt bij begrijpen wat er over
de lijn gaat, waar die berichten leven, welke afspraken er gemaakt worden tussen
partijen, en het automatiseren van documentatie, code en validatie. Dit is van
toegevoegde waarde in asynchrone use cases; voor synchrone is OAS meer dan
toereikend, ongeacht wat AsyncAPI op hun voorpagina heeft staan.</p>
<p>Op dit moment wordt er in een werkgroep van diverse experts gewerkt om AsyncAPI
te vertalen naar de Nederlandse digitale overheid. Deze groep richt zich erop om
een breed gedragen kennisplatform te bouwen, waar de volgende aandachtspunten op
de voorgrond staan:</p>
<ol>
<li class="">Uitzoeken hoe de standaard in elkaar zit; wat kun je ermee, hoe werkt het,
welke tools zijn er? Etc.</li>
<li class="">Uitwerken waar de standaard wel en niet voor geschikt is</li>
<li class="">Specifieke use cases van ondersteuning voorzien in het uitwerken van hun
implementatie van een asynchrone API keten, om daarmee ook punt 1 en 2 verder
uit te werken.</li>
</ol>
<p>De eerste observatie in de groep, op basis van hoe AsyncAPI zich op hun eigen
website presenteert, is dat AsyncAPI vaak wordt gepositioneerd als de asynchrone
tegenhanger van OpenAPI. Die vergelijking bleek in de praktijk niet dusdanig
strak op te gaan. Waar OpenAPI draait om request-response interacties tussen
bekende partijen, richt AsyncAPI zich op events, berichtenstromen en
ontkoppeling. Dat verschil lijkt op papier misschien klein, maar werkt door in
vrijwel elke keuze die je maakt: van hoe je documentatie structureert tot hoe je
verantwoordelijkheden in een keten interpreteert. OAS zou wel degelijk voor
asynchrone situaties gebruikt kunnen worden; PubSub webhooks worden bijvoorbeeld
gewoon ondersteund in OAS.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="vingers-aan-de-knoppen">Vingers aan de knoppen<a href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe#vingers-aan-de-knoppen" class="hash-link" aria-label="Direct link naar Vingers aan de knoppen" title="Direct link naar Vingers aan de knoppen" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="1-op-1-conversie">1-op-1 conversie<a href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe#1-op-1-conversie" class="hash-link" aria-label="Direct link naar 1-op-1 conversie" title="Direct link naar 1-op-1 conversie" translate="no">​</a></h3>
<p>Om beter grip op de nuances te krijgen hebben we een bestaande reeks
API-specificaties waarin al sprake was van asynchrone communicatie omgezet naar
een AsyncAPI documentatie; zie
<a href="https://studio.asyncapi.com/?share=d36cdf7f-1b42-4ac9-98a9-3194912fbfa0" target="_blank" rel="noopener noreferrer" class="">hier</a>
en
<a href="https://studio.asyncapi.com/?share=2cf00f8e-6aea-484c-b213-47d7cea70fd2" target="_blank" rel="noopener noreferrer" class="">hier</a>
voor links naar een aantal resultaten. In eerste instantie is er puur een 1-op-1
conversie gemaakt, met als doel om te zien hoe ver we kwamen zonder het
onderliggende ontwerp aan te passen. Wat daarbij opviel is dat die conversie
verrassend goed te doen is. Handmatige conversie van een relatief simpele API
aan de hand van de
<a href="https://www.asyncapi.com/docs/reference/specification/v3.1.0" target="_blank" rel="noopener noreferrer" class="">specificatie</a> was
een goede eerste stap om de spec beter te leren kennen, maar kostte wel tijd.
Desondanks bleek het relatief eenvoudig om Endpoints en Hostnames te vertalen
naar Channels, Payloads naar Messages en bestaande schema’s grotendeels te
hergebruiken. De beschikbare <a href="https://www.asyncapi.com/docs/tools" target="_blank" rel="noopener noreferrer" class="">tooling</a>
helpt hier aanzienlijk bij; validatie, documentgeneratie en zelfs
conversiefunctionaliteit maken het mogelijk om vrij snel tot een werkbare
specificatie te komen.</p>
<p>In het uitvoeren van deze “simpele” conversie werd er een belangrijk punt
zichtbaar. Een succesvolle conversie betekent namelijk niet automatisch dat je
ook een betere of meer passende beschrijving hebt gemaakt van je systeem. In
veel gevallen bleek de AsyncAPI-specificatie in essentie hetzelfde te
beschrijven als de oorspronkelijke OpenAPI-variant, alleen in een ander formaat.
Ja, het is nu in een documentatievorm die specifiek is toegespitst op asynchroon
verkeer, maar de vraag blijft of het wel nodig is. Ja, de berichtenstroom was
explicieter gemaakt, maar de onderliggende architectuur bleef ongewijzigd.
Daarmee ontstaat een situatie waarin je wel asynchrone documentatie hebt, maar
nog geen Event-Driven ontwerp. Kortom, we kunnen nog een stap verder.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="event-driven-herontwerp">Event-Driven herontwerp<a href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe#event-driven-herontwerp" class="hash-link" aria-label="Direct link naar Event-Driven herontwerp" title="Direct link naar Event-Driven herontwerp" translate="no">​</a></h3>
<p>Voor één van de casussen hebben we dus precies dit gedaan; in plaats van een
simpele conversie is er een volledig Event-Driven documentatie in AsyncAPI
opgeschreven. Waar de 1-op-1 conversie nog sterk leunde op bestaande endpoints
en interactiepatronen dwong het herontwerp ons om fundamenteel anders te kijken
naar het systeem. De 1-op-1 conversie was een goede eerste stap in dit proces;
doordat alles al naar AsyncAPI vertaald was konden bepaalde zaken zoals
channels, operations, messages e.a. makkelijk overgenomen worden. Het resultaat
is een ontwerp waarin Events werden leidend in plaats van Calls, meerdere
Consumers konden onafhankelijk op dezelfde gebeurtenis reageren en de keten van
acties werd losgekoppeld in plaats van expliciet georkestreerd. In die context
kwam AsyncAPI veel beter tot zijn recht, omdat het precies datgene beschrijft
waar het voor bedoeld is: het gedrag en de structuur van berichten in een
ontkoppeld landschap. Voor de geïnteresseerden,
<a href="https://studio.asyncapi.com/?share=6148b38e-94f7-4dc0-9f6f-10b75b5f1a02" target="_blank" rel="noopener noreferrer" class="">hier</a>
is een link naar een EDA-versie van de inventaris API hier eerder gelinkt.</p>
<p>Deze stap vereiste uiteraard beduidend meer werk dan een 1-op-1 conversie. Waar
de tooling goed ondersteunt bij het omzetten en valideren van specificaties,
laat het de daadwerkelijke architectuurkeuzes volledig bij de gebruiker. Het
herinterpreteren van bestaande documentatie naar een Event-Driven model vraagt
om inhoudelijke keuzes, afstemming tussen betrokken partijen en een goed begrip
van de implicaties van ontkoppeling. Met andere woorden: AsyncAPI faciliteert,
maar dwingt niets af; dit is één van de schoonheden van de specificatie.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="tooling">Tooling<a href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe#tooling" class="hash-link" aria-label="Direct link naar Tooling" title="Direct link naar Tooling" translate="no">​</a></h2>
<p>Ook op het gebied van tooling kwamen interessante observaties naar voren. Over
het algemeen is de volwassenheid hoog; validatie werkt betrouwbaar, documentatie
is snel te genereren en codegeneratie biedt duidelijke voordelen in termen van
consistentie en snelheid. Er zijn diverse
<a href="https://www.asyncapi.com/docs/tools/generator/template" target="_blank" rel="noopener noreferrer" class="">templates</a> voor
allerlei soorten code en applicaties beschikbaar “out of the box”, met ruimte om
zelf je eigen templates te ontwikkelen en beheren. Er zit hier op dit moment wel
een sterke externe afhankelijkheid in; denk hierin aan de black-box nature van
de default templates, versies van tooling en het gekozen perspectief binnen de
specificatie. In één geval bleek bijvoorbeeld dat om een bepaald type code te
genereren de documentatie naar een lagere versie gebracht moest worden, maar dat
daardoor ook het perspectief van de API documentatie zou wijzigen, namelijk van
producer naar consumer. Dit was al eerder een vraag binnen de werkgroep: vanuit
welk perspectief moet men AsyncAPI lezen? Het staat in de specificatie
aangegeven (3.x en hoger schrijven vanuit de producer, alles daaronder vanuit
consumer), maar dit wordt niet meteen duidelijk uit een API document zelf.
Dergelijke afhankelijkheden en mogelijkheden tot foute interpretatie maken het
des te belangrijker dat er een gebruikstandaard wordt opgesteld, hetzij binnen
een organisatie danwel binnen de gehele context van de Nederlanse Overheid.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="toepasbaarheid-en-toekomst">Toepasbaarheid en Toekomst<a href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe#toepasbaarheid-en-toekomst" class="hash-link" aria-label="Direct link naar Toepasbaarheid en Toekomst" title="Direct link naar Toepasbaarheid en Toekomst" translate="no">​</a></h2>
<p>Uit deze voorbeelden en degenen die door anderen in de werkgroep zijn
aangedragen zijn we naast beter begrip van de technische werking ook een stuk
wijzer geworden over de toepasbaarheid van AsyncAPI. In omgevingen waarin
meerdere systemen onafhankelijk van elkaar events publiceren en consumeren, en
waarin niet altijd vooraf bekend is wie welke informatie gebruikt, helpt een
expliciet contract enorm om overzicht te creëren. Zeker wanneer berichten
complex zijn of regelmatig veranderen biedt de combinatie van duidelijke
schema’s en tooling voor validatie en generatie een stevige basis om fouten en
misinterpretaties te voorkomen. Hetzelfde geldt voor bredere Event-Driven
landschappen, waarin inzicht in de keten en de impact van wijzigingen cruciaal
is om het geheel beheersbaar te houden.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="wanneer-asyncapi-minder-waarde-toevoegt">Wanneer AsyncAPI minder waarde toevoegt<a href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe#wanneer-asyncapi-minder-waarde-toevoegt" class="hash-link" aria-label="Direct link naar Wanneer AsyncAPI minder waarde toevoegt" title="Direct link naar Wanneer AsyncAPI minder waarde toevoegt" translate="no">​</a></h3>
<p>Daar tegenover staan situaties waarin die meerwaarde een stuk minder evident is.
In eenvoudige koppelingen tussen twee systemen, zeker wanneer beide onder
dezelfde verantwoordelijkheid vallen, voegt het expliciet modelleren van events
en contracten vaak weinig toe. Hetzelfde geldt voor kleine, eenduidige berichten
of omgevingen waarin nauwelijks sprake is van verandering over tijd. In dat
soort gevallen kan de overhead van uitgebreide specificaties en bijbehorende
tooling zwaarder wegen dan de voordelen die het oplevert. Sterker nog, wanneer
documentatie niet actief wordt bijgehouden, kan het zelfs een risico vormen
doordat het een vertekend beeld geeft van de werkelijkheid.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="conclusie">Conclusie<a href="https://developer.overheid.nl/blog/2026/05/28/asyncapi-1-tot-nu-toe#conclusie" class="hash-link" aria-label="Direct link naar Conclusie" title="Direct link naar Conclusie" translate="no">​</a></h2>
<p>De belangrijkste les die uit deze exercitie naar voren komt, is dan ook dat
AsyncAPI vooral gezien moet worden als een middel, en niet als een doel op zich.
Het is een krachtig instrument om asynchrone communicatie inzichtelijk te maken,
te standaardiseren en deels te automatiseren, maar het vervangt geen
architectuurkeuzes, geen governance en geen samenwerking tussen teams. Of het
daadwerkelijk waarde toevoegt, hangt sterk af van de context waarin het wordt
toegepast en de mate waarin organisaties bereid zijn om de bijbehorende
werkwijze te omarmen. Dit is echter een onderwerp en-sich, en dus spaar ik die
op voor de volgende blogpost!</p>]]></content>
        <author>
            <name>Floris Deutekom</name>
        </author>
        <category label="API" term="API"/>
        <category label="API Design" term="API Design"/>
        <category label="AsyncAPI" term="AsyncAPI"/>
        <category label="Event Driven Architecture (EDA)" term="Event Driven Architecture (EDA)"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Kadaster stelt Generieke Geo Componenten open source beschikbaar]]></title>
        <id>https://developer.overheid.nl/blog/2026/05/18/generieke-geo-componenten</id>
        <link href="https://developer.overheid.nl/blog/2026/05/18/generieke-geo-componenten"/>
        <updated>2026-05-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Digitale kaartinformatie, ook wel geo-informatie genoemd, is voor een organisatie als het Kadaster onmisbaar.
]]></summary>
        <content type="html"><![CDATA[<p><img decoding="async" loading="lazy" alt="Generieke Geo Componenten" src="https://developer.overheid.nl/assets/images/generieke-geo-componenten-7d266f8c2506f16f0dc7576defff5b55.png" width="1128" height="651" class="img_rVHu"></p>
<p>Digitale kaartinformatie, ook wel geo-informatie genoemd, is voor een
organisatie als het Kadaster onmisbaar. De eenvoudigste manier om geo-informatie
te bekijken en te gebruiken, is via een online kaartviewer. Diverse
kaartviewers, zoals de <a href="https://app.pdok.nl/viewer" target="_blank" rel="noopener noreferrer" class="">PDOK Viewer</a>, het
<a href="https://wozwaardeloket.nl/" target="_blank" rel="noopener noreferrer" class="">WOZ-waardeloket</a> en de
<a href="https://bagviewer.kadaster.nl/" target="_blank" rel="noopener noreferrer" class="">BAG Viewer</a>, zijn door het Kadaster ontwikkeld
om geodata eenvoudig te raadplegen en te gebruiken.</p>
<p>Wat minder zichtbaar is bij het gebruik van deze viewers, is dat ze 'onder de
motorkap' dezelfde componenten gebruiken: de
<a href="https://www.generiekegeocomponenten.nl/" target="_blank" rel="noopener noreferrer" class="">Generieke Geo Componenten</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="waarom-generieke-geo-componenten">Waarom Generieke Geo Componenten?<a href="https://developer.overheid.nl/blog/2026/05/18/generieke-geo-componenten#waarom-generieke-geo-componenten" class="hash-link" aria-label="Direct link naar Waarom Generieke Geo Componenten?" title="Direct link naar Waarom Generieke Geo Componenten?" translate="no">​</a></h2>
<p>Binnen het Kadaster worden veel kaartviewers ontwikkeld voor interne en externe
doeleinden. We hebben ze nooit officieel geteld, maar naar schatting zijn het er
40 à 50. Vaak worden deze viewers ontwikkeld door afzonderlijke ontwikkelteams.</p>
<p>Het BAG-team is bijvoorbeeld verantwoordelijk voor de volledige dienstverlening
rondom de Basisregistratie Adressen en Gebouwen (BAG). Zij zorgen ervoor dat
bronhouders (gemeenten) BAG-data kunnen registreren, dat deze correct wordt
opgeslagen in de landelijke voorziening en dat de gegevens via API's en andere
webservices beschikbaar worden gesteld aan gebruikers. Daarnaast zijn zij ook
verantwoordelijk voor de ontwikkeling en het beheer van de BAG Viewer.</p>
<p>Doordat veel teams op deze manier werkten, ontstond er zo'n tien jaar geleden
een versnipperd landschap aan kaartviewers. De viewers maakten gebruik van
verschillende technieken, zagen er onderling anders uit ondanks dezelfde
huisstijl en voldeden niet altijd aan eisen op het gebied van toegankelijkheid
en responsiveness. Daarbij lag de focus van veel ontwikkelteams vooral op
backends en databases, waardoor het ontwikkelen en beheren van een kaartviewer
er vaak 'bij' werd gedaan. Dit leidde ertoe dat in elk team telkens opnieuw het
wiel werd uitgevonden.</p>
<p>Om dit te doorbreken zijn de Generieke Geo Componenten ontwikkeld: flexibele
softwarebouwstenen waarmee ontwikkelaars, ook zonder veel frontendkennis,
eenvoudig een online kaartviewer kunnen maken. Ze werken met de
geo-informatiestandaarden die PDOK gebruikt voor open geodata en ondersteunen
het principe 'data bij de bron'. Ook voldoen ze, waar mogelijk, aan de
toegankelijkheidsrichtlijnen (WCAG), al geldt voor geo-informatie deels een
uitzondering.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="waarom-open-source">Waarom open source?<a href="https://developer.overheid.nl/blog/2026/05/18/generieke-geo-componenten#waarom-open-source" class="hash-link" aria-label="Direct link naar Waarom open source?" title="Direct link naar Waarom open source?" translate="no">​</a></h2>
<p>Al vroeg in de ontwikkeling van de Generieke Geo Componenten ontstond het idee
om deze buiten het Kadaster beschikbaar te maken. De componenten zijn namelijk
gebaseerd op open‑sourceframeworks zoals OpenLayers en Angular. Daarnaast zagen
we dat andere overheidsorganisaties tegen vergelijkbare uitdagingen aanliepen,
of juist onvoldoende capaciteit hadden om zelf een kaartviewer te ontwikkelen.
Open software kan bovendien helpen bij het vergroten van de adoptie van open
data en open standaarden.</p>
<p>Toch strandde dit plan eind 2017, na het verschijnen van een
<a href="https://www.kennisopenbaarbestuur.nl/documenten/2017/10/11/onderzoek-open-source-software" target="_blank" rel="noopener noreferrer" class="">rapport van Gartner</a>.
Hierin werd gewezen op mogelijke juridische risico's in het kader van de Wet
Markt en Overheid. De focus verschoof daarom naar intern gebruik, terwijl we
verder werkten aan het verbeteren van de componenten en het stimuleren van het
gebruik binnen het Kadaster.</p>
<p>De ambitie verdween tijdelijk naar de achtergrond, maar bleef bestaan. Inmiddels
zijn zowel het overheidsbeleid als het Kadasterbeleid rond open source
gewijzigd. We zijn dan ook blij dat we tijdens de Open Geodag van 12 mei de
Generieke Geo Componenten alsnog hebben kunnen vrijgeven.</p>
<p>Een bijkomend voordeel is dat de componenten in de tussentijd rijker zijn
geworden in functionaliteit en zich in de praktijk hebben bewezen: ze worden
inmiddels in zo'n 30 applicaties binnen het Kadaster gebruikt.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="actief-samenwerken-aan-doorontwikkeling">Actief samenwerken aan doorontwikkeling<a href="https://developer.overheid.nl/blog/2026/05/18/generieke-geo-componenten#actief-samenwerken-aan-doorontwikkeling" class="hash-link" aria-label="Direct link naar Actief samenwerken aan doorontwikkeling" title="Direct link naar Actief samenwerken aan doorontwikkeling" translate="no">​</a></h2>
<p>We nodigen iedereen uit om een kijkje te nemen op
<a href="https://www.generiekegeocomponenten.nl/" target="_blank" rel="noopener noreferrer" class="">https://www.generiekegeocomponenten.nl</a>.</p>
<p>Hier kun je voorbeelden bekijken, de componenten gebruiken en bijdragen aan de
verdere ontwikkeling. Op de website vind je ook een link naar GitHub en
technische documentatie om de componenten te installeren en te configureren.
Voor het Kadaster is dit een van de eerste serieuze
open‑sourcesoftwarepublicaties. We kijken uit naar de extra dynamiek en
samenwerking die dit oplevert voor de verdere doorontwikkeling van de
componenten.</p>]]></content>
        <author>
            <name>Jaap-Willem Sjoukema</name>
        </author>
        <category label="Front-end" term="Front-end"/>
        <category label="Geodata" term="Geodata"/>
        <category label="Open Source" term="Open Source"/>
        <category label="Toegankelijkheid" term="Toegankelijkheid"/>
        <category label="WCAG" term="WCAG"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Kom naar onze meetup op 17 juni: Samen. Beter. Bouwen.]]></title>
        <id>https://developer.overheid.nl/blog/2026/05/12/event-17-juni</id>
        <link href="https://developer.overheid.nl/blog/2026/05/12/event-17-juni"/>
        <updated>2026-05-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Op 17 juni organiseren we een nieuwe developer.overheid.nl meetup in Utrecht. Een middag voor developers, architecten en makers binnen de overheid die willen bouwen, leren en ervaringen uitwisselen.
]]></summary>
        <content type="html"><![CDATA[<p>Hoe bouwen we binnen de overheid software die open, veilig, herbruikbaar én
dienstbaar is aan de samenleving?</p>
<p>Op woensdag 17 juni organiseren we een nieuwe developer.overheid.nl meetup in
Utrecht. Een middag voor developers, architecten, platform engineers, tech leads
en makers binnen de overheid die willen bouwen, leren en ervaringen uitwisselen.</p>
<p>Geen beleidsverhalen, maar concrete praktijkvoorbeelden, demo's, open source
tooling en gesprekken met mensen die hier dagelijks aan werken.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>TL;DR</div><div class="admonitionContent_ZZhP"><p>We organiseren 17 juni een meetup met hands-on demo's en praktijkvoorbeelden.
Aanmelden kan via
<a href="https://opensourcewerken.nl/events/view/28756611-d38b-40c1-8f87-4ac8433831dd/developeroverheidnl-meetup" target="_blank" rel="noopener noreferrer" class="">opensourcewerken.nl</a>
of mail naar <a href="mailto:v.vanderheijden@geonovum.nl" target="_blank" rel="noopener noreferrer" class="">v.vanderheijden@geonovum.nl</a>.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="op-het-programma">Op het programma<a href="https://developer.overheid.nl/blog/2026/05/12/event-17-juni#op-het-programma" class="hash-link" aria-label="Direct link naar Op het programma" title="Direct link naar Op het programma" translate="no">​</a></h2>
<ul>
<li class="">
<p><strong>Platform engineering</strong> — Anne Schuth<br>
<!-- -->Waarom is de Nederlandse overheid misschien wel het grootste softwarebedrijf
van Nederland. En waarom moeten we ons ook zo organiseren.</p>
</li>
<li class="">
<p><strong>AI Skill: publiccode.yml generator</strong> — Tom Ootes<br>
<!-- -->Hoe je met AI Skills automatisch een publiccode.yml genereert en AI inzet
binnen je ontwikkelproces.</p>
</li>
<li class="">
<p><strong>DON-checker</strong> — Dimitri van Hees<br>
<!-- -->Live demo van de vernieuwde DON-checker voor het toetsen op standaarden en kwaliteit.</p>
</li>
<li class="">
<p><strong>Code.overheid.nl</strong> — Johan Groenen<br>
<!-- -->Over code.overheid.nl; een nieuwe gedeelde gitomgeving voor de overheid, gebouwd
op Forgejo, opgezet door OSPO BZK als antwoord op de groeiende vraag naar digitale
soevereiniteit en een alternatief voor GitHub.</p>
</li>
<li class="">
<p><strong>OpenKAT</strong> — Jan Klopper<br>
<!-- -->Een open source securitytool met een actieve community en slimme plugins
("boefjes") voor het analyseren van netwerken en systemen.</p>
</li>
<li class="">
<p><strong>Open mic &amp; vooruitblik</strong><br>
<!-- -->Welke tooling, standaarden of use cases wil jij de volgende keer zien?</p>
</li>
<li class="">
<p><strong>Borrel bij Ruig</strong></p>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="praktische-informatie">Praktische informatie<a href="https://developer.overheid.nl/blog/2026/05/12/event-17-juni#praktische-informatie" class="hash-link" aria-label="Direct link naar Praktische informatie" title="Direct link naar Praktische informatie" translate="no">​</a></h2>
<table><thead><tr><th></th><th></th></tr></thead><tbody><tr><td>📅 Datum</td><td>17 juni 2026</td></tr><tr><td>🕒 Tijd</td><td>12:30 – 16:00 (aanvang met lunch)</td></tr><tr><td>📍 Locatie</td><td>Utrecht, boven het Beatrixtheater</td></tr><tr><td>✉️ Aanmelden</td><td>Via <a href="https://opensourcewerken.nl/events/view/28756611-d38b-40c1-8f87-4ac8433831dd/developeroverheidnl-meetup" target="_blank" rel="noopener noreferrer" class="">opensourcewerken.nl</a> of mail naar <a href="mailto:v.vanderheijden@geonovum.nl" target="_blank" rel="noopener noreferrer" class="">v.vanderheijden@geonovum.nl</a></td></tr></tbody></table>
<br>
<p style="font-size:1.75rem"></p><p>Word contributor.</p><p></p>
<p>We zien je op 17 juni!</p>]]></content>
        <author>
            <name>Tom Ootes</name>
        </author>
        <category label="Meetups" term="Meetups"/>
        <category label="Community" term="Community"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[De softe kant van standaarden: adoptie vraagt om gelaagde communicatie]]></title>
        <id>https://developer.overheid.nl/blog/2026/05/07/softe-kant-van-standaarden</id>
        <link href="https://developer.overheid.nl/blog/2026/05/07/softe-kant-van-standaarden"/>
        <updated>2026-05-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Hoe bevorder je adoptie van standaarden? Maak gebruik van persona's en stem informatie over standaarden af op hun behoeften.
]]></summary>
        <content type="html"><![CDATA[<p>Standaarden zijn vaak technisch van aard. Ze zorgen voor interoperabele
oplossingen die technisch op elkaar kunnen aansluiten. Als we kijken naar
adoptie van standaarden, dan is dat vaak een soft verhaal: "Wat heb ik
hieraan?", "Is het verplicht?", "Doen anderen het ook?". Dit soort vragen worden
door verschillende persona's gesteld en elke persona vereist een andere aanpak
om te overtuigen van het nut van een standaard.</p>
<p>Bij het bevorderen van adoptie van standaarden is het van groot belang dat de
softe kant op orde is. De keuze om een standaard te implementeren heeft een
grotere impact als een bestuurder die maakt, dan één individuele developer. Zelf
doe ik mee aan de werkgroep
<a href="https://realisatieibds.nl/groups/view/0056c9ef-5c2e-44f9-a998-e735f1e9ccaa/federatief-datastelsel/wiki/view/794e40b9-9b98-494c-9242-6380409088e5/werkgroep-adoptie-standaarden" target="_blank" rel="noopener noreferrer" class="">"Adoptie van standaarden"</a>
binnen het
<a href="https://realisatieibds.nl/page/view/564cc96c-115e-4e81-b5e6-01c99b1814ec/de-ontwikkeling-van-het-federatief-datastelsel" target="_blank" rel="noopener noreferrer" class="">Federatief Datastelsel</a>
(FDS), om te analyseren welke activiteiten nuttig zijn om adoptie te bevorderen.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span><strong>TL;DR</strong></div><div class="admonitionContent_ZZhP"><p>Adoptie van standaarden is geen technisch, maar een menselijk vraagstuk. Door je
te verdiepen in de juiste persona's: <strong>bestuurder</strong>, <strong>architect</strong>,
<strong>developer</strong> vergroot je de kans op adoptie aanzienlijk.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="het-verkopen-van-nee">Het verkopen van "nee"<a href="https://developer.overheid.nl/blog/2026/05/07/softe-kant-van-standaarden#het-verkopen-van-nee" class="hash-link" aria-label="Direct link naar Het verkopen van &quot;nee&quot;" title="Direct link naar Het verkopen van &quot;nee&quot;" translate="no">​</a></h2>
<p>Standaardisatie is in essentie de kunst van het verkopen van "nee". Voorheen was
elke gekozen oplossingsrichting mogelijk, met een standaard worden daar keuzes
in gemaakt. Dit is per definitie restrictief: eerst mocht je alles en nu niet
meer. Onbewust is dat ook het eerste signaal wat mensen ontvangen: "Nu moet ik
het op deze specifieke manier doen, waarom dan?".</p>
<p>Bij het bevorderen van standaardisatie is het cruciaal om te realiseren dat
restricties nooit fijn zijn. Elk mens waardeert de (persoonlijke) keuzevrijheid,
zeker in het federatieve overheidslandschap van honderden overheidsorganisaties
die grotendeels autonoom beslissingen willen maken. Daarom is in mijn optiek de
focus op "nu kan je dit niet meer" geen handige tactiek. Je staat al 1-0 achter
voordat het gesprek begint.</p>
<p>De focus verleggen naar "als we dit afspreken, dan kan je ineens X-Y-Z" is een
positievere boodschap. Door af te spreken om alle mogelijke gegevens die
uitgewisseld kunnen worden in formaat F vast te leggen, is het bijvoorbeeld
mogelijk om efficiëntere aansluitingen te realiseren. De voordelen bij
gegevensuitwisseling zijn er voor beide partijen:</p>
<ol>
<li class="">de afnemer weet dat het er altijd vanuit kan gaan dat het in formaat F is
vastgelegd, zodat elke uitwisseling op dezelfde manier verloopt</li>
<li class="">de aanbieder heeft baat bij uniformiteit omdat hij bij de nieuwe integratie
van een afnemer exact hetzelfde endpoint kan bieden</li>
</ol>
<p>Hier hebben beide partijen baat bij, ook al mogen ze nu minder dan wat voorheen
toegestaan was. Restricties leveren in dit geval wel degelijk waarde op.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="hoe-krijgen-we-de-focus-op-de-positieve-kant">Hoe krijgen we de focus op de positieve kant?<a href="https://developer.overheid.nl/blog/2026/05/07/softe-kant-van-standaarden#hoe-krijgen-we-de-focus-op-de-positieve-kant" class="hash-link" aria-label="Direct link naar Hoe krijgen we de focus op de positieve kant?" title="Direct link naar Hoe krijgen we de focus op de positieve kant?" translate="no">​</a></h2>
<p>De uitdaging bij standaardisatie is om de focus van restricties te verleggen
naar de positieve kant. Dit is het gespreksonderwerp van de werkgroep "Adoptie
van standaarden" bij het FDS. Vanaf de eerste werksessie werd de focus gelegd op
de softe kant, iets waar ik positief verrast door was. "Fijn dat er
gelijkgestemden hier bijeenkomen die realiseren hoe belangrijk die softe kant
is" dacht ik toen.</p>
<p>Het was wel nog zoeken hoe we deze softe kant kunnen belichten. We vroegen ons
af wie de belanghebbenden zijn bij de keuze voor standaarden en wat hun
beweegredenen zijn. Hiervoor hebben we enkele persona's uitgewerkt, om structuur
te kunnen geven aan de discussies.</p>
<p>De persona's waar we voor nu op focusen zijn:</p>
<ol>
<li class="">Programmamanager bij een overheidsorganisatie</li>
<li class="">Architect bij een overheidsorganisatie</li>
<li class="">Developers (bij een leverancier)</li>
</ol>
<p>Elke persona heeft andere wensen, eisen en bewegingsruimte. Tevens heeft de ene
persona meer invloed dan de andere op bepaalde gebieden. Hierbij is het
belangrijk om te weten "wie er aan welke tafel zit" om te bepalen waar het
gesprek over een standaard plaats vindt.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-bestuurlijke-hoek-bepaalt">De bestuurlijke hoek bepaalt<a href="https://developer.overheid.nl/blog/2026/05/07/softe-kant-van-standaarden#de-bestuurlijke-hoek-bepaalt" class="hash-link" aria-label="Direct link naar De bestuurlijke hoek bepaalt" title="Direct link naar De bestuurlijke hoek bepaalt" translate="no">​</a></h2>
<p>Voor de bestuurlijke hoek is het van belang om te begrijpen wat er speelt en hoe
een oplossing daaraan bijdraagt. Vaak wordt op dit niveau nagedacht over
prioriteit, tijd en geld. Met standaarden is het dus van belang om duidelijk te
krijgen hoe een standaard bijvoorbeeld tijd of geld bespaart, waardoor het
prioriteit verdient.</p>
<p>Er is ingezet om een overzicht te krijgen op welke gebieden bepaalde standaarden
de meeste waarde realiseren. Hieruit is een overzichtsplaat voortgekomen die
laat zien voor welke stelselfuncties binnen het FDS welke standaarden passen:</p>
<p><img decoding="async" loading="lazy" alt="Overzicht van stelselfuncties van FDS met bijbehorende standaarden" src="https://developer.overheid.nl/assets/images/overzichtsplaat-stelselfuncties-fds-f3a386ca918f5c2c67021f85469088f3.png" width="1189" height="595" class="img_rVHu">
<em>Deel van de overzichtsplaat zoals gepubliceerd op
<a href="https://federatief.datastelsel.nl/kennisbank/stelselfuncties/#de-technische-stelselfuncties" target="_blank" rel="noopener noreferrer" class="">de website van FDS</a>
(geraadpleegd op 2026-04-01)</em></p>
<p>Zo'n overzicht is te printen voor op een banner, of eenvoudig toe te voegen aan
een presentatie. Dat is ook de werkomgeving van de bestuurlijke hoek: overleggen
met anderen wat er gedaan moet worden. Hierbij is een overzicht nuttig om te
laten zien wat er mogelijk is en dat er al analyses zijn gedaan welke standaard
het beste toepasbaar is.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Vind de verbinding</div><div class="admonitionContent_ZZhP"><p>Aansluiten bij de werkomgeving van de persona is van belang om het juiste
bericht te kunnen versturen. Persona's die opereren in de bestuurlijke hoek
hebben baat bij informatie in een overzichtelijk formaat.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="architecten-als-sturing">Architecten als sturing<a href="https://developer.overheid.nl/blog/2026/05/07/softe-kant-van-standaarden#architecten-als-sturing" class="hash-link" aria-label="Direct link naar Architecten als sturing" title="Direct link naar Architecten als sturing" translate="no">​</a></h2>
<p>Bestuurders vragen zich ook vaak af: "Oke, maar is dit wel uit te voeren in mijn
organisatie?" Hierbij is het noodzakelijk om het technische landschap van een
organisatie te kennen en hier een visie op te hebben. Daar komt de rol van een
architect bij kijken, waarbij het voor standaarden belangrijk is dat een
architect begrijpt hoe zo'n standaard past in het totaalplaatje.</p>
<p>Om dit duidelijker te krijgen zijn er handreikingen geschreven. De eerste versie
van de handreikingen staan inmiddels
<a href="https://www.noraonline.nl/wiki/Standaarden_in_het_Federatief_Datastelsel" target="_blank" rel="noopener noreferrer" class="">online op NORA</a>.</p>
<oproep><p>Op dit moment zijn we op zoek naar feedback op deze handreikingen. Laat feedback
achter op NORA met concrete verbeteringen en suggesties.</p></oproep>
<p>De handreikingen gaan meer in detail ten opzichte van de overzichtsplaat. Ze
bevatten generieke informatie over de standaard, de impact die het heeft, maar
ook de relaties tot andere standaarden. Dat sluit mooi aan op de originele
vraagstukken waar een architect aan werkt: hoe past in het geheel?</p>
<p>Mogelijk valt het ook op hoe de handreikingen een positieve toon hebben. Er
wordt aangegeven wat er mogelijk is als de standaard wordt geïmplementeerd en
aan welke architectuurprincipes ze invulling geven. Daarnaast wordt er ook
ingegaan op impact, want er zullen altijd ook andere consequenties zijn waar
rekening mee moet worden gehouden.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Begrijp de technische eisen</div><div class="admonitionContent_ZZhP"><p>Zorg ervoor dat een standaard compatibel is met bestaande oplossingen. Maak
duidelijk hoe de technische relaties er uit zien.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="developers-als-de-doeners">Developers als de doeners<a href="https://developer.overheid.nl/blog/2026/05/07/softe-kant-van-standaarden#developers-als-de-doeners" class="hash-link" aria-label="Direct link naar Developers als de doeners" title="Direct link naar Developers als de doeners" translate="no">​</a></h2>
<p>Als een bestuurder het nut inziet en een architect de mogelijkheden, is het nog
wel de zaak dat het ook uitvoerbaar is. Hier komt de doelgroep van developers
(al dan niet in-house of werkzaam bij een leverancier) in beeld. Developers
willen graag concrete instructies hoe een standaard toe te passen is en hoe het
mogelijk is om te checken of daaraan wordt voldaan.</p>
<p>Deze vraagstukken worden dan bij uitstek hier in de kennisbank op
<a href="https://developer.overheid.nl/" target="_blank" rel="noopener noreferrer" class="">developer.overheid.nl</a> beantwoord. Bijvoorbeeld
voor
<a href="https://logius-standaarden.github.io/logboek-dataverwerkingen/" target="_blank" rel="noopener noreferrer" class="">Logboek Dataverwerkingen</a>
zijn er
<a href="https://developer.overheid.nl/kennisbank/data/standaarden/logboek-dataverwerkingen/implementaties/jakarta" target="_blank" rel="noopener noreferrer" class="">concrete codevoorbeelden</a>
en links naar
<a href="https://developer.overheid.nl/kennisbank/data/standaarden/logboek-dataverwerkingen/implementaties/go" target="_blank" rel="noopener noreferrer" class="">referentie-implementaties</a>
die inspiratie kunnen bieden aan de doeners.</p>
<p>Om te checken of er wordt voldaan aan een standaard kunnen validators worden
gebruikt. De
<a href="https://developer-overheid-nl.github.io/oas-checker/#/adr-21" target="_blank" rel="noopener noreferrer" class="">OAS checker</a> is
gebouwd om geautomatiseerd te valideren of een OpenAPI specificatie voldoet aan
de
<a href="https://gitdocumentatie.logius.nl/publicatie/api/adr/" target="_blank" rel="noopener noreferrer" class="">REST API Design Rules</a>.
Validators worden steeds belangrijker, zeker in een tijdperk waarin code
genereren met behulp van AI wordt toegepast.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Zet in op validatie</div><div class="admonitionContent_ZZhP"><p>Developers vinden het fijn om duidelijke doelen te krijgen en concluderen dat ze
eraan voldoen. Zet in op validatie-technieken en automatisering van testen om
het einddoel te bepalen.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="conclusie-de-crux-van-adoptie-zit-in-de-gelaagdheid">Conclusie: de crux van adoptie zit in de gelaagdheid<a href="https://developer.overheid.nl/blog/2026/05/07/softe-kant-van-standaarden#conclusie-de-crux-van-adoptie-zit-in-de-gelaagdheid" class="hash-link" aria-label="Direct link naar Conclusie: de crux van adoptie zit in de gelaagdheid" title="Direct link naar Conclusie: de crux van adoptie zit in de gelaagdheid" translate="no">​</a></h2>
<p>Elk van deze persona's heeft invloed op de (mogelijke) adoptie van een
standaard. Als op een van de lagen het nut niet wordt gezien, het onduidelijk is
hoe het past in het geheel of dat het niet uit te voeren is, resulteert dat vaak
in het wegblijven van adoptie. Het scherp hebben van de eisen van een doelgroep
helpt in het positief positioneren van een standaard.</p>
<p>Focus niet op maar één persona in de hoop dat het balletje dan vanzelf gaat
rollen. Analyseer of een standaard iets mist aan communicatie op een bepaalde
laag en focus daar op. Mijn hoop is dat de werkgroep later met nog meer
informatie komt hoe dit aan te pakken.</p>]]></content>
        <author>
            <name>Tim van der Lippe</name>
        </author>
        <category label="Adoptie" term="Adoptie"/>
        <category label="Standaarden" term="Standaarden"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[We gaan samen code.overheid.nl bouwen]]></title>
        <id>https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen</id>
        <link href="https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen"/>
        <updated>2026-04-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Op 24 april was de softlaunch van code.overheid.nl: één gedeelde gitomgeving voor de overheid, gebouwd op Forgejo. In deze blogpost bespreken we wat er nodig is om dat tot een succes te maken: beginnen met bouwen, en samenwerken.]]></summary>
        <content type="html"><![CDATA[<p>24 april was ik bij de softlaunch van code.overheid.nl. Het is een project dat
bij veel developers en organisaties aanslaat omdat elke developer een gitomgeving nodig
heeft om überhaupt samen te kunnen werken. Sinds er veel aandacht uit gaat naar
digitale soevereiniteit is de roep om een gezamenlijke gitomgeving alleen maar
gegroeid, het werd steeds minder voordehandliggend om op Github te blijven.</p>
<p>Vanuit dit besef heeft OSPO BZK zich hard gemaakt voor de opzet van
code.overheid.nl, in de vorm van een Forgejo instance.</p>
<p>Voor meer informatie over waarom Forgejo nou precies de juiste keuze is, verwijs
ik je graag door naar de blogpost van Jan Vlug:
<a href="https://developer.overheid.nl/blog/2025/11/11/git-forge-overheid" target="_blank" rel="noopener noreferrer" class=""><strong>"Aanbeveling voor de Git-werkplaats van de overheid"</strong></a>.</p>
<div class="theme-admonition theme-admonition-success admonition_jS7q alert alert--success"><div class="admonitionHeading_C48g"><span class="admonitionIcon_ALcI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span><strong>TL;DR</strong></div><div class="admonitionContent_ZZhP"><p>code.overheid.nl is een nieuwe gedeelde gitomgeving voor de overheid, gebouwd op
Forgejo. Het platform bevindt zich in de pilotfase en wordt <strong>samen met
developers</strong> gebouwd. Om dit tot een succes te maken moeten we samen aan de
slag. Wil je meebouwen? Stuur een mail naar
<a href="mailto:codeplatform@rijksoverheid.nl" target="_blank" rel="noopener noreferrer" class="">codeplatform@rijksoverheid.nl</a>.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="onmisbare-schakel">Onmisbare schakel<a href="https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen#onmisbare-schakel" class="hash-link" aria-label="Direct link naar Onmisbare schakel" title="Direct link naar Onmisbare schakel" translate="no">​</a></h2>
<p>Als developer.overheid.nl is het ons doel om het leven van developers zo
makkelijk mogelijk te maken en die developer in staat stellen om hoge kwaliteit
software te bouwen.</p>
<p>De manier waarop we daar nu in voorzien is door middel van een kennisbank,
tooling en een aantal producten. Ook draaien we verschillende checks op ons Open
Source- en API-register en zorgen we zo voor kwaliteitsmonitoring. Echter zijn
we voor het vullen van beide registers afhankelijk van organisaties voor het
inzenden van hun repositories en API's. Bovendien hebben we geen directe toegang
tot deze git omgevingen en kunnen we niet direct samenwerken met deze
organisaties om bijvoorbeeld templates, tools en pipelines te delen.</p>
<p>Hoe mooi zou het zijn als we juist met z'n allen, dus met welwillende developers
en organisaties een eigen gitplatform bouwen, zodat we onze tooling en zo onze
werkwijzen gemakkelijk met elkaar kunnen delen. Pas dan zijn we echt in staat om
ook gezamenlijk aan tooling te werken. Het stelt ons in staat om allemaal stukje
bij beetje op dezelfde manier te gaan developen. Hier zie ik een grote rol voor
code.overheid.nl weggelegd.</p>
<p>Dat is de kans die we nu hebben, dat we eindelijk een plek hebben waar we kunnen
samenwerken en van elkaar kunnen leren.</p>
<p><img decoding="async" loading="lazy" alt="./img/gina.jpg" src="https://developer.overheid.nl/assets/images/gina-dd1f4b2e9079662b9f731275ced271a0.jpg" width="3024" height="1701" class="img_rVHu"> <em>Gina Plat van OSPO BZK</em></p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="zo-beginnen-we">Zo beginnen we<a href="https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen#zo-beginnen-we" class="hash-link" aria-label="Direct link naar Zo beginnen we" title="Direct link naar Zo beginnen we" translate="no">​</a></h2>
<p>Hoe beginnen we hier mee? Door als verschillende organisaties met elkaar in
gesprek te gaan over wat we nog nodig hebben om het platform op dagelijkse basis
te kunnen gebruiken. En nog belangrijker, dat we <strong>beginnen te bouwen</strong>. Dat kan
om te beginnen gewoon door middel van het inschieten van issues, om het gesprek
te starten, en door middel van het maken van PR's.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="de-doelgroep-zit-aan-tafel">De doelgroep zit aan tafel<a href="https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen#de-doelgroep-zit-aan-tafel" class="hash-link" aria-label="Direct link naar De doelgroep zit aan tafel" title="Direct link naar De doelgroep zit aan tafel" translate="no">​</a></h2>
<p>Wat mij betreft is de insteek van code.overheid.nl slim omdat je niet iets bouwt
<strong>voor</strong> een gebruikersgroep (developers) maar <strong>met</strong>. Dit minimaliseert de
kans dat je energie in iets stopt waarvan je achteraf moet concluderen dat het
helemaal niet nuttig was.</p>
<p>En omdat de organisaties zelf ook energie stoppen in het bouwen van features, en
dus skin in the game hebben, zullen ze eerder geneigd zijn het gebruik ervan aan
te moedigen of te verplichten.</p>
<p><img decoding="async" loading="lazy" alt="./img/boris.jpg" src="https://developer.overheid.nl/assets/images/boris-0d2de6e07f2641f971d77513679b01af.jpg" width="2703" height="1520" class="img_rVHu"> <em>Boris van Hoytema van OSPO BZK</em></p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="pilot">Pilot<a href="https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen#pilot" class="hash-link" aria-label="Direct link naar Pilot" title="Direct link naar Pilot" translate="no">​</a></h2>
<p>Op dit moment bevindt code.overheid.nl zich in de pilotfase. Dit betekent dat
nog niet iedere overheidsorganisatie zich kan aanmelden en er gebruik van kan
maken. De reden hiervoor is dat er gekozen is voor een graduele aanpak waarbij
langzaam maar zeker een volwaardig gitplatform ontstaat.</p>
<h3 class="anchor anchorTargetStickyNavbar_P5PD" id="nog-niet-af">Nog niet af<a href="https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen#nog-niet-af" class="hash-link" aria-label="Direct link naar Nog niet af" title="Direct link naar Nog niet af" translate="no">​</a></h3>
<p>Op dit moment kan dus nog niet de hele overheid ge-onboard worden, maar dat is
in mijn optiek logisch. We moeten voorkomen dat het beeld ontstaat dat het nog
niet af is, want het is in feite nog niet af, maar dat komt vooral doordat we
het nog niet gebouwd hebben.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="meedoen">Meedoen<a href="https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen#meedoen" class="hash-link" aria-label="Direct link naar Meedoen" title="Direct link naar Meedoen" translate="no">​</a></h2>
<p>Maar heeft jouw team bijvoorbeeld al ervaring met Forgejo en zijn jullie nu al
zelf nuttige features aan het bouwen? dan is het mogelijk om nu al aangehaakt te
raken. Hiervoor kan je contact opnemen met:
<a href="mailto:codeplatform@rijksoverheid.nl" target="_blank" rel="noopener noreferrer" class="">codeplatform@rijksoverheid.nl</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="herinnering-aan-mezelf">Herinnering aan mezelf<a href="https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen#herinnering-aan-mezelf" class="hash-link" aria-label="Direct link naar Herinnering aan mezelf" title="Direct link naar Herinnering aan mezelf" translate="no">​</a></h2>
<p>Deze blogpost wil ik ook graag gebruiken als een herinnering aan mezelf om me te
commiteren aan code.overheid.nl. Het blijven zorgen voor een project in de vorm
van issues, ideeën en pull requests is iets wat een hoop geduld vereist. Vooral
omdat je er ineens voor moet gaan <em>samenwerken</em>.</p>
<p>Dat zie ik ook gebeuren bij de publiccode.yml-standaard waaraan ik bijdraag. De
meeste tijd gaat zitten in het koppelen van mensen en het bespreken van ideeën,
voordat het daadwerkelijk in de standaard zelf terecht komt.</p>
<h2 class="anchor anchorTargetStickyNavbar_P5PD" id="conclusie">Conclusie<a href="https://developer.overheid.nl/blog/2026/04/24/we-gaan-samen-code-overheid-bouwen#conclusie" class="hash-link" aria-label="Direct link naar Conclusie" title="Direct link naar Conclusie" translate="no">​</a></h2>
<p>Bij deze dus de uitnodiging om code.overheid.nl in de gaten te houden en indien
mogelijk mee te bouwen. Alleen samen komen we tot een volwaardig Github
alternatief.</p>
<p>Ben je klaar om mee te bouwen? Meld je dan aan via de "Meedoen"-sectie
hierboven.</p>]]></content>
        <author>
            <name>Tom Ootes</name>
        </author>
        <category label="Git" term="Git"/>
        <category label="Open Source" term="Open Source"/>
    </entry>
</feed>