Tekst
<p>Dit deel van de architectuur beschrijft architectuuraspecten die van belang zijn bij het notificeren over gebeurtenissen. Het start met een uitleg van de terminologie die specifiek in dit hoofdstuk wordt gehanteerd. Deze terminologie is gebaseerd op de CloudEvents standaard en is te zien als een doorvertaling van de meer algemene begrippen in dit document, naar de invulling voor op applicatieniveau. Vervolgens gaat het hoofdstuk in op de applicatie-architectuur en de relevante standaarden.</p>
<h3>Terminologie</h3>
<p>Als we spreken over notificeren, refereren we in meer algemene zin naar een gebeurtenisgedreven werkwijze. Daarbij notificeren aanbieders afnemers en verstrekken ze daarbij gegevens over plaatsgevonden gebeurtenissen. Voorafgaand daaraan abonneren afnemers zich door aan te geven voor welke typen gebeurtenissen zij genotificeerd willen worden. De plaatsgevonden gebeurtenissen zijn de trigger om gegevens uit te wisselen. Het initiatief daarvoor ligt bij de aanbieder die gegevens verstrekt over binnen zijn domein plaatsgevonden gebeurtenissen (“don’t call us, we’ll call you”). Deze manier van gegevens uitwisselen is fundamenteel anders dan wanneer een aanbieder een service aanbiedt en afnemers zelf het initiatief nemen om gegevens op te gaan halen. Beide vormen van gegevensuitwisseling hebben bestaansrecht, maar kennen een specifiek toepassing en kunnen ook in combinatie worden gebruikt. Gebruikers van smartphones vinden het vanzelfsprekend dat zij kunnen aangeven voor welke type gebeurtenissen zij notificaties willen ontvangen.
</p><p>
Notificeren is een onderdeel van eventoriëntatie. Daarbij is het belangrijk om snel te kunnen reageren op gebeurtenissen in processen. Dat kunnen levensgebeurtenissen zijn; belangrijke gebeurtenissen in het leven van een burger. Notificeren kan ook op een meer technisch niveau relevant zijn, bijvoorbeeld om anderen te attenderen op wijzigingen in gegevens. Notificeren kan ook dataminimalisatie ondersteunen, door het notificeren over gegevenswijzigingen los te zien van het ophalen van de specifieke (persoons)gegevens die relevant zijn in een specifiek proces.
</p><p>
Een veelgebuikt patroon bij notificeren is “publish-and-subscribe”. Daarbij produceren applicaties (producers) berichten over plaatsgevonden gebeurtenissen (events). Afnemende applicaties (consumers) nemen een abonnement (subscription) op bepaalde soorten berichten. Makelaars (intermediairies) kunnen bemiddelen tussen producers en consumers om gepubliceerde events aan de juiste consumers te verstrekken. Consumers ontvangen de soorten events waarop ze zijn geabonneerd. Onderstaande figuur geeft de beschreven rolverdeling weer.</p>
<p><img src="https://minbzk.github.io/gdi-gegevensuitwisseling/images/cloudevents.svg"></p>
<p>Applicaties kunnen eigendom zijn van één of meerdere organisaties en kunnen (in verschillende samenstellingen) ook gecombineerd zijn. Bij een uitwisseling kunnen één of meerdere intermediairs een rol spelen. De afspraken tussen betrokken partijen over de gegevensuitwisseling zijn sterk vergelijkbaar met de algemeen geldende afspraken bij gegevensuitwisseling. </p>
<h3>Applicatie-architectuur</h3>
<p>De functionaliteit voor abonneren wordt op dit moment veelal geboden via interactieve schermen. Daarop kan een gebruiker aangeven welke soorten events hij wel en niet willen ontvangen. Het kan gaan om eenvoudige invulschermen of om schermen waarmee een gebruiker zelf complexe selectieregels kan definiëren. Soms wordt aanvullend de mogelijkheid geboden om periodiek geautomatiseerd bepaalde filtergegevens aan te leveren. Bijvoorbeeld in de vorm van een periodiek aangeleverd bestand of via een API waarmee een afnemer gegevens aanlevert die worden gebruikt om events te filteren. Een voorbeeld hiervan is een verzameling BSN’s van personen waarvoor events moeten worden verstrekt.
</p><p>
Het is ook mogelijk om abonnementen geautomatiseerd via API’s vast te leggen, te wijzigen of verwijderen. Dit biedt nieuwe mogelijkheden, zoals het afsluiten van (heel) veel kleine abonnementen waarin in detail is beschreven in welke events een afnemer is geïnteresseerd. Bijvoorbeeld door per persoon waarvoor genotificeerd moeten worden een eigen abonnement af te sluiten.
</p><p>
Abonneren krijgt in deze architectuur beperkt aandacht omdat de noodzaak van standaardisatie nu minder groot is en omdat gestandaardiseerd geautomatiseerd abonneren zeer complex is. De belangrijkste reden hiervoor is dat voor een standaard veel soorten metagegevens nodig zijn om in alle situaties bruikbaar te zijn, waardoor de standaard snel (te) complex wordt. Het zelf ontwikkelen van een abonneerstandaard is niet wenselijk, maar het is wel wenselijk om internationale ontwikkelingen op dit vlak te volgen en te zijner tijd daarop aan te sluiten.
</p><p>
Notificeren gaat over het verzenden van events. Een event is een data record dat een plaatsgevonden gebeurtenis beschrijft. Het bevat metagegevens over context voor bijvoorbeeld het kunnen routeren van het event van producers naar consumers en het bevat inhoudelijke informatie over de plaatsgevonden gebeurtenis of een verwijzing naar waar die is te vinden. Events worden getransporteerd via, gestructureerde of binaire, berichten. Voor een event wordt gebruik gemaakt van een bepaald formaat (bijv. JSON of XML) en transportprotocol (bijv. HTTP of AMQP). Bij notificeren gaat het in het algemeen over gebeurtenissen die hebben plaatsgevonden (‘feiten’), niet over gebeurtenissen in de toekomst.
</p><p>
Voor notificeren zijn een aantal functionaliteiten relevant: routeren, filteren en verstrekken. Routeren is het fysiek transporteren van events zodat ze vanuit producers bij consumers terecht komen. Filteren is het binnen alle gepubliceerde events, per consumer selecteren van de juiste events. Verstrekken is het beschikbaar stellen van events aan consumers via een bezorg- of ophaalmechanisme.
</p><p>
Bij notificeren kan de communicatie tussen applicaties synchroon of asynchroon verlopen. Bij Asynchrone communicatie wacht de verzender niet op een antwoord van de ontvanger. Asynchrone communicatie biedt voordelen qua schaalbaarheid, flexibiliteit, foutbestendigheid en efficiëntie bij notificeren. Een notificatie die niet kan worden verstrekt omdat een consumer niet actief is kan dan bijvoorbeeld door een intermediair worden bewaard en op een later moment als de consumer actief is alsnog worden verstrekt. Bij gebeurtenisgedreven werken, inclusief notificeren, verdient asynchrone communicatie daarom de voorkeur. </p>
<h3>Standaarden</h3>
<p>Van 2021 tot 2023 is in opdracht van het Ministerie van Binnenlandse Zaken het <a href="https://github.com/VNG-Realisatie/notificatieservices/tree/main/docs/achtergronddocumentatie">project ‘Notificatieservices’</a> uitgevoerd. Een van de doelen daarvan was om een advies te geven over een standaard voor notificeren. Er is besloten om daarvoor voort te bouwen op de internationale standaard <a href="https://cloudevents.io/">CloudEvents</a>. Deze standaard is gekozen omdat deze het beste aansluit bij de aanwezige behoeften en mogelijkheden van Nederlandse overheidsorganisaties. De <a href="https://semiceu.github.io/LinkedDataEventStreams/">Linked Data Event Streams</a> standaard was nog in ontwikkeling en op dat moment (nog) te weinig toepasbaar. De standaard is wel in combinatie met de CloudEvents standaard te gebruiken. CloudEvents wordt vanaf 2018 ontwikkeld binnen de Cloud Native Computing Foundation (CNCF) via een community met onder andere Cloud leveranciers zoals Microsoft, Google en Amazon. Tijdens het project Notificatieservices is door onderzoeksbureau Gartner bevestigd dat de CloudEvents-standaard voldoende toekomst vast was om als basis te gebruiken.
</p><p>
<a href="https://www.asyncapi.com/">AsyncAPI</a> is de de facto standaard voor het definiëren van asynchroon werkende API’s en wordt vaak vergeleken met OpenAPI specification. Met behulp van AsyncAPI zijn onder andere het formaat van berichten, de uit te voeren operaties en te gebruiken protocollen gestandaardiseerd te beschrijven. Dit bevordert de kwaliteit van documenteren, ontwerpen, testen en gebruiken van asynchroon werkende API’s. AsyncAPI is onderdeel van de Linux Foundation en wordt actief onderhouden door een open-sourcegemeenschap. De standaard kent een groeiend ecosysteem van tools en bibliotheken die AsyncAPI-specificaties kunnen verwerken, zoals codegeneratoren, validatietools, integraties met API-gateways en meer. AsyncAPI is te combineren met CloudEvents. CloudEvents helpt bij het definiëren van het formaat van de gebeurtenissen en AsyncAPI helpt bij het definiëren van de gebeurtenisgestuurde API's. Dat zijn API’s die zijn ontworpen om te reageren op notificaties van gebeurtenissen. AsyncAPI kan worden gebruikt om de API en het bijbehorende CloudEvent-formaat te documenteren.
</p><p>
Naarmate er meer eventgeoriënteerd wordt gewerkt wordt het steeds belangrijker om daarbij betrokken metagegevens gestandaardiseerd vast te leggen en raadplegen. Om events goed te kunnen verwerken moet bekend zijn om wat voor soort event het gaat en wat de precieze betekenis daarvan is. Hiervoor kan gebruik worden gemaakt van catalogi met de beschrijving van eventtypes en hun relaties. Het is wenselijk dat dit type documentatie wordt gestandaardiseerd omdat consumers met steeds meer producers en soorten events te maken krijgen.
<h3>De CloudEvents standaard in meer detail</h3>
<p>
Omdat er in een eerder onderzoek vooral is gekozen voor het gebruik van de CloudEvents standaard, wordt deze hier in meer detail uitgelegd. CloudEvents kent een compacte ‘core specificatie’ voor gestandaardiseerde beschrijving van events. Aanvullend zijn er specificaties voor gebruik van de core specificatie met specifieke gegevensformaten (bijvoorbeeld JSON en XML) en transportprotocollen (bijvoorbeeld HTTP en AMQP). Standaardisatie strekt zich daarmee uit tot en met implementatieaspecten. Er zijn door de community ondersteunende producten ontwikkeld, zoals System Development Kits (SDK) voor veelgebruikte programmeertalen.
</p><p>
Er is een Nederlands profiel op de CloudEvents standaard ontwikkeld: <a href=”https://www.logius.nl/domeinen/gegevensuitwisseling/nl-gov-profile-cloudevents”>NL GOV profile for CloudEvents</a>. Het bevat een set afspraken over het gebruik van de internationale CloudEvents standaard binnen de Nederlandse overheid. Het beschrijft bijvoorbeeld welke (aanvullende) afspraken gelden met betrekking tot het gebruik van bepaalde attributen. Naast het profiel zelf is er een document <a href=”https://gitdocumentatie.logius.nl/publicatie/notificatieservices/guidelines/”>Guidelines for NL-GOV profile CloudEvents</a> dat gebruik van de standaard beschrijft bij gebruik van respectievelijk HTTP, JSON, webhooks. Het profiel en de handreiking zijn in beheer bij Logius. Het is de bedoeling dat het profiel op afzienbare termijn wordt opgenomen in de lijst van open standaarden van het Forum Standaardisatie.
</p><p>
Het centrale begrip in de CloudEvents standaard is ‘event’: een data record met metadata. Het bevat contextattributen om te kunnen notificeren en inhoudelijke gegevens over een plaatsgevonden gebeurtenis (of een verwijzing daarnaar). Een viertal metagegevens moeten volgens de CloudEvents specificatie, en het daarop gebaseerde NL GOV Profile for CloudEvents, altijd aanwezig zijn binnen een event:
<ul>
<li>Een unieke identificatie voor het event (‘id’)</li>
<li>De bron van het event (‘source’)</li>
<li>De versie van de gebruikte CloudEvents-specificatie (‘specversion’)</li>
<li>Het eventtype (‘type’)</li>
</ul>
<p>
Het GOV NL profile for CloudEvents bevat afspraken over hoe deze attributen binnen de overheid moeten worden gebruikt. In een event kunnen ook aanvullende metagegevens worden opgenomen. CloudEvents heeft een aantal vaak voorkomende metagegevens gedefinieerd, maar ze zijn ook zelf te definiëren. Dit kan bijvoorbeeld op sector- of domeinniveau gebeuren.
</p><p>
Ook bij gebruik van het NL GOV Profile for CloudEvents is er ruimte voor betrokken organisaties om eigen keuzes te maken. Bijvoorbeeld wat betreft in events op te nemen metagegevens, het wel of niet opnemen van inhoudelijke data in berichten en gebruikte gegevensformaten, transportprotocollen en technische infrastructuur. Gegevens in een subscription kunnen zowel handmatig als geautomatiseerd worden bijgewerkt. Een samengestelde applicatie kan applicatiecomponenten combineren. Het initiatief voor verstrekking kan liggen bij intermediary of consumer.
</p>