diff --git a/blog/draft/asyncapi-1-tot-nu-toe.md b/blog/draft/asyncapi-1-tot-nu-toe.md new file mode 100644 index 00000000..ceefc901 --- /dev/null +++ b/blog/draft/asyncapi-1-tot-nu-toe.md @@ -0,0 +1,189 @@ +--- +authors: [floris-deutekom] +tags: [api, api-design, asyncapi, eda] +description: | + 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. +--- + +# AsyncAPI: verkenning en eerste bevindingen + +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. + + + +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. + +## AsyncAPI + +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 +[Event-Driven Architecture](https://developer.overheid.nl/blog/2026/03/06/event-driven) +in zijn algemeen. Het is tevens een voortborduursel op het werk van +[OpenAPI Initiative](https://developer.overheid.nl/kennisbank/api-ontwikkeling/standaarden/openapi-specification/), +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. + +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: + +1. Uitzoeken hoe de standaard in elkaar zit; wat kun je ermee, hoe werkt het, + welke tools zijn er? Etc. +2. Uitwerken waar de standaard wel en niet voor geschikt is +3. 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. + +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. + +## Vingers aan de knoppen + +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 +[hier](https://studio.asyncapi.com/?share=d36cdf7f-1b42-4ac9-98a9-3194912fbfa0) +en +[hier](https://studio.asyncapi.com/?share=2cf00f8e-6aea-484c-b213-47d7cea70fd2) +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 +[specificatie](https://www.asyncapi.com/docs/reference/specification/v3.1.0) 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 [tooling](https://www.asyncapi.com/docs/tools) +helpt hier aanzienlijk bij; validatie, documentgeneratie en zelfs +conversiefunctionaliteit maken het mogelijk om vrij snel tot een werkbare +specificatie te komen. + +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. + +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, +[hier](https://studio.asyncapi.com/?share=6148b38e-94f7-4dc0-9f6f-10b75b5f1a02) +is een link naar een EDA-versie van de inventaris API hier eerder gelinkt. + +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. + +## Tooling + +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 +[templates](https://www.asyncapi.com/docs/tools/generator/template) 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. + +## Toepasbaarheid en Toekomst + +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. + +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. + +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! diff --git a/blog/draft/asyncapi-2-use-cases.md b/blog/draft/asyncapi-2-use-cases.md new file mode 100644 index 00000000..e93c0114 --- /dev/null +++ b/blog/draft/asyncapi-2-use-cases.md @@ -0,0 +1,248 @@ +--- +authors: [floris-deutekom] +tags: [api, api-design, asyncapi, eda] +description: | + 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. +--- + +# AsyncAPI: Wanneer wel? Wanneer niet? + +In een eerdere blogpost zijn de eerste bevindingen van de werkgroep +[AsyncAPI](https://www.asyncapi.com/en) gedeeld na het uitwerken van een tweetal +use cases waarin asynchrone API’s van [OAS](https://www.openapis.org/) 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. + + + +## Toegevoegde waarde van AsyncAPI + +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. + +### Onbekende afnemers + +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. + +### 1-op-N communicatie + +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 -> 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. + +### Ontkoppelde request-response flows + +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. + +### Complexe/grote landschappen + +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. + +### Veranderlijk landschap + +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. + +### Complexe/grote berichten + +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). + +### Event-Driven omgevingen + +Al deze kenmerken komen samen in omgevingen waarin +[Event-Driven Architecture](https://developer.overheid.nl/blog/2026/03/06/event-driven) +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. + +## OAS als betere optie + +Kortom, AsyncAPI biedt een hoop mogelijkheden. Het is echter zeker niet +alomvattend, ongeacht wat er op de [Roadmap](https://www.asyncapi.com/roadmap) +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. + +### Simpele integraties; 1-op-1 koppelingen + +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. + +### Simpele/kleine berichten + +Een vergelijkbaar beeld ontstaat bij kleine of eenduidige berichten; denk aan +simpele status berichten als een `{ "status": "ok" }`. 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. + +### Low-use omgevingen + +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. + +### Statische omgevingen + +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. + +### Onvolwassen organisaties + +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. + +## Voorlopige conclusie + +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. + +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. diff --git a/blog/draft/asyncapi-3-implementatie-met-cloudevents.md b/blog/draft/asyncapi-3-implementatie-met-cloudevents.md new file mode 100644 index 00000000..760fafb9 --- /dev/null +++ b/blog/draft/asyncapi-3-implementatie-met-cloudevents.md @@ -0,0 +1,206 @@ +--- +authors: [floris-deutekom] +tags: [api, api-design, eda, asyncapi, CloudEvents] +description: | + 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. +--- + +# AsyncAPI + CloudEvents; implementatie van asynchrone oplossingen + +In de voorgaande blogposts hebben we gekeken naar wat +[AsyncAPI](https://www.asyncapi.com/en) 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? + + + +## CloudEvents + +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. + +In een +[eerdere blogpost](https://developer.overheid.nl/blog/2026/03/06/event-driven) +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. + +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. + +[CloudEvents](https://CloudEvents.io/) 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 +[NL GOV profiel](/kennisbank/api-ontwikkeling/standaarden/CloudEvents) en door +[Forum Standaardisatie](https://www.forumstandaardisatie.nl/open-standaarden/nl-gov-profile-CloudEvents) +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. + +## Toepasgebied + +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. + +### Notificaties + +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. + +### Cross-team integraties + +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. + +### Auditing en replay + +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. + +## Hoe dit aan te pakken? + +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. + +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. + +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. + +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. + +## Kijkje naar de toekomst + +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 +[niet de enigen](https://www.asyncapi.com/blog/asyncapi-cloud-events) die de +link tussen deze twee gezien heeft; binnen AsyncAPI is vanaf het begin al waarde +gezien in het combineren van CloudEvents en AsyncAPI. + +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. + +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!