DCB en het gevolgenjournaal
Deze verdieping sluit aan bij het instapverhaal van event sourcing naar betrouwbaar register.
In 2023 ontplofte er een bom in de event sourcing wereld: Sara Pellegrini stond in een Kill Bill outfit op de Axoniq conferentie 2023 met de stelling: 'Kill the Aggregate'. In haar blogpost legt ze uit waarom. Ze introduceerde met haar blog de 'dynamic consistency boundary', afgekort DCB: een nieuwe manier om beslissingen te nemen over het afhandelen en verwerken van commando's. Sara is mede-initiator van de site dcb.events, wat als achtergrond en referentie gebruikt kan worden voor deze methodiek.
In dit hoofdstuk leggen we uit wat de DCB is, wat de perspectieven daarop zijn in de event sourcing wereld en hoe het gevolgenjournaal in de handreiking zich hiertoe verhoudt.
Wat is de dynamic consistency boundary?
In een wat meer traditionele event sourcing aanpak draaiden events rond aggregates: elk event is gekoppeld aan één aggregate. Als een nieuw commando afgehandeld moet worden, wordt de aggregate geladen met alle eerdere events op deze aggregate en wordt het commando gevalideerd tegen deze aggregate. De aggregate dient als consistency boundary: het bepaalt de collectie events die gebruikt worden om nieuwe commando's tegen te valideren.
Dit werkt prima bij een commando als RegistreerPersoon of RegistreerWoonAdres. Wat is de aggregate die hier bij hoort? De persoon. Geef elke persoon in je registratie een nummer en je kan deze commando's prima afhandelen. Maar wat doe je met RegistreerHuwelijk? Hier wordt één aggregate problematisch voor het afhandelen: op welke aggregate moet dit commando afgehandeld worden? Is huwelijk zelf een aggregate? Dit commando gaat echter ook over 2 personen die niet getrouwd mogen zijn.
Door de consistency boundary niet te limiteren tot één aggregate, maar de grens waartegen een commando gevalideerd wordt flexibeler te maken, is het mogelijk om events te publiceren die over meerdere 'aggregates' gaan. In plaats van commando's te redirecten naar één aggregate, moet je per commando bepalen wat de set van events is waartegen je dit commando valideert: de consistency boundary wordt flexibel. Bij een RegistreerHuwelijk kun je dan bijvoorbeeld een combinatie van events van de twee partners en hun (eerdere) huwelijken (en scheidingen) laden. Zie ons implementatievoorbeeld voor de details van de implementatie van een huwelijkscommando.
Tags of geen tags?
Om de DCB te kunnen implementeren schrijft dcb.events voor dat events één of meerdere tags als metadata moeten krijgen, dat naast het type gebruikt wordt om te kunnen query'en op events, voor zowel opvragingen als bij het verwerken van commando's (het bepalen van de consistency boundary). Daarnaast blijft de payload (de event data) van een event voor de event store een black box: voor het selecteren van een set events wordt niet gekeken naar de inhoud van het event.
Rico Fritzsche, in Event Stores and Tags: A Misunderstood Optimization beargumenteert in zijn blog tegen tags: hij stelt dat taggen een externe interpretatie oplegt aan event(payload)s die prematuur is: "Let the event store be the source of truth and not the source of structure. Let correlation happen downstream. Let meaning emerge. Let consumers decide." De DCB moet bepaald worden aan de hand van interpretatie van de payload, die dus inhoudelijk bekend (genoeg) moet zijn voor de event store om dat te kunnen doen. "It (tags) introduces a black-and-white mindset into a system that thrives in shades of grey."
Het register en de DCB
Als we kijken naar de handreiking ten opzichte van deze verschillen van inzichten zijn er een aantal relevante punten die we kunnen maken over een betrouwbaar overheidsregister (afgekort: register):
- Een gevolg (een event in het register) moet gaan over entiteiten
- Een register moet zich kunnen verantwoorden met herkomst en legitimering.
- Een register moet kunnen betwijfelen en onttrekken
Dit betekent dat een register meer eisen stelt aan haar gevolgen dan een event sourcing framework doet aan haar events. We dwingen structuur en betekenis af. In een betrouwbaar overheidsregister zeggen we expliciet niet: "Let meaning emerge. Let consumers decide". Het register bepaalt zelf wat de gevolgen precies betekenen. Afnemers zijn vrij om daar nieuwe, of andere interpretaties aan te geven, maar dergelijke interpretaties liggen nadrukkelijk buiten de bounded context van het register.
Door de route van dcb.events te kiezen behalen we nog een aantal andere voordelen:
- We kunnen expliciet duidelijk maken 'waar het register van is': de entiteiten die we erkennen (door ze te taggen) maken de bounded context van het register ook duidelijker.
- We kunnen goede indices maken op deze kenmerken.
- We kunnen als event store agnostisch blijven over de vorm van de payload, wat ruimte geeft aan
upcasting(todo link naar uitleg), encryptie of zelfs het vernietigen van payloads.
De handreiking heeft nooit aggregates gekend: de eenheid van betekenis is de entiteit, de eenheid van de beslissing is het commando. De handreiking zegt dat laatste uitdrukkelijk: "de opnametoestand is een uit het gevolgenjournaal afgeleide toestand waartegen wordt vastgesteld of een commando tot gevolgen kan leiden" (zie de handreiking) en die wordt per commando samengesteld, niet per entiteit. "Kill the aggregate" is voor de handreiking dus geen bedreiging maar een bevestiging: wat DCB dynamic noemt is precies wat een opnametoestand al is. De DCB sluit dus perfect aan en beschrijft voor ons criteria van implementatie.
Qua implementatiekeuze neigen we dus nadrukkelijk naar de dcb.events-versie. In Effectively zijn we begonnen met een daadwerkelijke framework-implementatie. In de komende periode willen we bovenstaande toetsen. Ons doel is om een profile voor 'betrouwbare overheidsregisters' te definiëren: Wat moet je (naast de standaard event sourcing technologie) daar bovenop doen om tot een betrouwbaar register te komen?