3.2

View in English

3.2 Architectuurstijlen en -patronen

Overzicht en motivatie

Een architectuurstijl is een brede, herbruikbare vorm om een systeem te organiseren: hoe het wordt ontleed, hoe de delen communiceren en waar de grenzen vallen. Er een kiezen is een van de meest ingrijpende (en meest verkeerd begrepen) beslissingen die een grote organisatie neemt. Te vaak volgt de keuze de mode (“iedereen doet microservices”) in plaats van de echte beperkingen van het team, het domein en de operationele werkelijkheid. Je eindigt met een van twee rommels: een gedistribueerd systeem dat de organisatie niet kan beheren, of een verstrengelde monoliet die niemand veilig kan wijzigen. Geen van beide is de schuld van de stijl. Beide komen voort uit het niet laten passen van de stijl op de situatie.

Voor grote ontwikkelteams doen stijlen er vooral toe vanwege de wet van Conway: de structuur van een systeem neigt de communicatiestructuur van de organisatie die het bouwt te weerspiegelen. Een architectuurstijl is dus ook een organisatieontwerpbeslissing. Een systeem in services splitsen is in werkelijkheid een beslissing over het splitsen van teams, eigenaarschap en verantwoordelijkheid voor bereikbaarheidsdienst. Ondernemingen met honderden engineers kunnen zich fijnmazige services met onafhankelijke deployment veroorloven (en hebben ze vaak nodig), omdat die onafhankelijkheid is hoe veel teams opleveren zonder elkaar te blokkeren. Leg hetzelfde patroon op aan één klein team en het erft alle operationele belasting zonder het organisatorische voordeel.

Overheids- en ondernemingsomgevingen stapelen meer beperkingen op: lange systeemlevensduur, strikte wijzigingsbeheersing, aanbestedingscycli, integratie met verankerde systemen van registratie en controleerbaarheid. Deze begunstigen stijlen die grenzen expliciet houden en afhankelijkheden makkelijk te inspecteren. Dit hoofdstuk geeft een overzicht van de grote stijlen: monoliet tot en met microservices, gebeurtenisgedreven architecturen met CQRS en event sourcing, service mesh- en gatewaypatronen, serverless en de interne disciplines van hexagonale en cleane architectuur. Belangrijker nog, het helpt je te zien wanneer elk past.

Zie ook: hoofdstuk 2.2 (ontwerpprincipes voor software, inclusief Domain-Driven Design), hoofdstuk 3.1 (architectuurfundamenten) en hoofdstuk 3.3 (gedistribueerde systemen).

Kernprincipes

  • Stijl volgt krachten, geen mode. Kies op basis van teamgrootte, domeincomplexiteit, belasting en operationele volwassenheid, nooit omdat een technologie populair is.
  • Koppeling is de echte vijand, niet het aantal deployables. Een goed gemodulariseerde monoliet verslaat een gedistribueerde big ball of mud.
  • Distributie is een kostenpost die je betaalt voor onafhankelijkheid. Splits alleen wanneer de waarde van onafhankelijke deployment, schaling of foutisolatie de kosten van netwerkaanroepen, gedeeltelijk falen en dataconsistentie over services overtreft.
  • Grenzen moeten het bedrijfsdomein volgen. Lijn services en modules uit met afgebakende contexten (elk een op zichzelf staand domeinmodel met eigen expliciete grens), niet met technische lagen.
  • Ontwerp het binnenste goed, ongeacht de buitenkant. Hexagonale/cleane gelaagdheid houdt bedrijfslogica onafhankelijk van frameworks en infrastructuur in elke stijl.
  • De wet van Conway is onontkoombaar, dus gebruik haar. Ontwerp teamgrenzen en architectuur samen.
  • Begin eenvoudiger dan je denkt nodig te hebben. Je kunt services uit een goede modulaire monoliet extraheren. Een voortijdige microservicerommel ongedaan maken is veel moeilijker.

Aanbevelingen

Kies standaard een modulaire monoliet, splits met bewijs

Begin de meeste systemen als één enkele deployable eenheid met sterke interne modulegrenzen: heldere interfaces, geen grijpen in de data van een andere module en afgedwongen afhankelijkheidsregels. Je krijgt eenvoudige transacties, makkelijke refactoring en één ding om te deployen en te observeren. Splits een module pas af in een eigen service wanneer je een concrete reden hebt: een onderdeel dat apart moet schalen, een team dat in een eigen ritme moet deployen, een faaldomein dat je moet isoleren of een technologievereiste die afwijkt van de rest. Wanneer je splitst, splits dan langs de lijnen van afgebakende contexten zodat elke service haar data bezit en een stabiel contract blootlegt.

Weet wanneer microservices hun plek verdienen

Microservices geven je onafhankelijke deploybaarheid, onafhankelijke schaling, foutisolatie en de vrijheid technologieën te mengen. In ruil eisen ze volwassen CI/CD (continuous integration en continuous delivery), geautomatiseerde infrastructuur, gedistribueerde tracing, servicediscovery en een cultuur van bereikbaarheidsdienst. Vraag jezelf eerlijk af: kan je organisatie tientallen onafhankelijk gedeployde services betrouwbaar in productie draaien? Als het platform en de operationele volwassenheid er niet zijn, vermenigvuldigen microservices alleen je faalwijzen zonder hun voordelen te leveren. Veel organisaties doen het best met een handvol grofmazige services afgestemd op grote domeinen in plaats van een zwerm kleine.

Gebruik gebeurtenisgedreven architectuur waar ontkoppeling en asynchroniciteit lonen

Gebeurtenisgedreven architectuur laat producenten feiten uitzenden zonder te weten wie ze consumeert. Dat koopt je losse koppeling, een buffer voor belastingpieken en een makkelijke manier om nieuwe consumenten toe te voegen. Gebruik haar waar werkstromen van nature asynchroon en reactief zijn. CQRS (Command Query Responsibility Segregation) scheidt het schrijfmodel van een of meer leesmodellen, wat helpt wanneer lees- en schrijfbelasting of -vormen sterk verschillen. Event sourcing slaat toestand op als een append-only log van gebeurtenissen in plaats van als huidige toestand, wat je een perfect auditspoor en tijdreizen geeft. Dat is krachtig voor financiën en overheid, waar “hoe kwamen we bij deze waarde?” een juridische vraag is, maar het voegt echte complexiteit toe bij het versioneren van gebeurtenissen, het herbouwen van projecties en het redeneren over uiteindelijke consistentie. Grijp hiernaar met opzet, niet standaard.

Pas gateway-, BFF- en meshpatronen toe om veel services te beheren

Een API-gateway geeft externe clients één ingangspunt, dat authenticatie, ratelimiting, routering en TLS-terminatie (Transport Layer Security) afhandelt. Een Backend-for-Frontend (BFF) geeft elk clienttype (web, mobiel, partner-API) zijn eigen op maat gemaakte aggregatielaag, zodat je een opgeblazen one-size-fits-all-API vermijdt. Een service mesh verplaatst dwarsdoorsnijdende zorgen (mutual TLS, herhalingen, time-outs, verkeersverschuiving en telemetrie) naar een sidecar-infrastructuurlaag, zodat applicatieteams ze niet opnieuw hoeven te implementeren. Voeg een mesh pas toe wanneer het aantal services het per service afhandelen van deze zorgen onbeheersbaar maakt. Voor een paar services is een mesh meer operationeel gewicht dan het waard is.

Weeg serverless eerlijk af

Function-as-a-service en beheerde serverlessplatforms nemen serverbeheer van je bord, schalen naar nul en rekenen per gebruik af, wat geweldig is voor piekerige, gebeurtenisgedreven of laag-basislijn werklasten en voor kleine teams. De afwegingen zijn echt: koudestartlatentie, limieten op uitvoeringstijd en middelen, moeilijker lokaal testen, mogelijke leverancierafhankelijkheid en kosten die bij aanhoudend hoog volume die van gereserveerde infrastructuur kunnen overschrijden. Gebruik serverless waar de economie en operationele eenvoud duidelijk winnen. Dwing stabiele kernsystemen met hoge doorvoer er niet in uit enthousiasme in.

Houd bedrijfslogica schoon binnen elke service

Ongeacht de buitenste stijl houd je het binnenste schoon met hexagonaal (poorten en adapters) of cleane architectuur: bedrijfsregels in het midden, alleen afhankelijk van abstracties, frameworks, databases en berichtenuitwisseling aan de randen als vervangbare adapters. Dit houdt je waardevolle domeinlogica testbaar zonder infrastructuur en overdraagbaar over technologieverandering: een beslissend voordeel voor langlevende overheids- en ondernemingssystemen die meerdere generaties frameworks zullen overleven.

Afwegingen: voor- en nadelen

StijlHet best wanneerVoordelenNadelen
Modulaire monolietDe meeste systemen, vooral vroegEenvoudige operatie, makkelijke transacties en refactoringEén deployeenheid. Schaalt als één. Risico van erosie
MicroservicesVeel teams, hoge schaal, volwassen platformOnafhankelijk deployen/schalen, foutisolatieGedistribueerde complexiteit, dataconsistentie, hoge operatiekosten
Gebeurtenisgedreven / CQRS / event sourcingAsynchrone werkstromen, auditbehoeften, uiteenlopend lezen/schrijvenLosse koppeling, controleerbaarheid, schaalbare leesactiesUiteindelijke consistentie, gebeurtenisversionering, moeilijker debuggen
ServerlessPiekerig of laag-basislijn, gebeurtenisgedreven werkGeen serverbeheer, schalen naar nul, betalen per gebruikKoude starts, limieten, afhankelijkheid, kosten bij hoge stabiele belasting

Het terugkerende thema: je koopt flexibiliteit en onafhankelijkheid met operationele en cognitieve complexiteit. Gedistribueerde en gebeurtenisgedreven stijlen geven de eenvoud van één aanroepstapel en één transactie op in ruil voor het vermogen onafhankelijk te schalen, deployen en falen. Die ruil betaalt zich uit op schaal en met een volwassen platform. Zonder is ze ruïneus. De interne disciplines (hexagonaal/clean) zijn bijna altijd de moeite waard, omdat ze weinig kosten en je opties openhouden om later van stijl te veranderen.

Vragen om met je team te bespreken

  1. Ga je, voordat je de volgende service splitst, ook het team splitsen dat haar bezit, en wie heeft daartoe de bevoegdheid? De wet van Conway betekent dat een servicegrens in werkelijkheid een teamgrens is, dus een splitsing die het organigram niet steunt produceert een gedistribueerde monoliet: twee deployables, één releasetrein, gedeelde bereikbaarheidsdienst. In een grote onderneming ligt de bevoegdheid teams te hervormen meestal boven engineering, bij rapportagelijnen, financiën en HR, daarom moeten architectuur en organisatieontwerp samen worden besloten. Neem bewijs mee naar de discussie: heeft de voorgestelde service een team dat haar van begin tot eind kan bezitten, zijn eigen bereikbaarheidsdienst kan bemannen en in een eigen ritme kan deployen? Als het antwoord nee is, financier dan het team of houd het vermogen als module in de monoliet. Code splitsen zonder eigenaarschap te splitsen koopt alle kosten van distributie en geen van de onafhankelijkheid.

  2. Kun je elk van je services vandaag onafhankelijk deployen, of leveren ze stiekem in gelijke pas op? De gedistribueerde monoliet is de slechtste uitkomst in dit hoofdstuk: je betaalt voor netwerkaanroepen, gedeeltelijk falen en dataconsistentie over services en kunt toch geen enkele releasen zonder de andere. De verklikkers zijn een gedeelde database, een gedeelde bibliotheek die gecoördineerde upgrades afdwingt en integratietests die het hele landschap samen moeten draaien. Voor een groot team begrenst dit stilletjes de doorvoer, omdat elk team achter één release in de rij staat ook al toont het diagram onafhankelijkheid. Neem één recente wijziging en tel hoeveel services samen moesten deployen om haar veilig te maken. Als dat getal groter is dan één voor een wijziging die één vermogen raakte, zijn je grenzen fout. De oplossing is meestal elke service haar eigen data en een stabiel, geversioneerd contract te geven, niet meer services toe te voegen.

  3. Welke van je bestaande servicesplitsingen betalen zich niet meer uit, en zou je ze weer consolideren? De meest geavanceerde gewoonte van het hoofdstuk is stijlbeslissingen als omkeerbaar te behandelen: extraheer wanneer een drijfveer verschijnt en voeg weer samen wanneer de drijfveer verdwijnt. De meeste organisaties splitsen alleen, zodat nanoservices en praatzieke entiteitsservices zich opstapelen tot orkestratie en netwerkoverhead het werk van elke service in de schaduw stellen. Zoek naar services die altijd samen deployen, die bestaan vanwege een databasetabel in plaats van een bedrijfsvermogen of waarvan de netwerkhops nu de latentie van een verzoek domineren. In ondernemings- en overheidslandschappen, waar formatie en budgetten onder de loep liggen, is twee dunne services terugvouwen tot één grofmazige service een legitieme, kostenbesparende zet, geen bekentenis van falen. Zet herconsolidatie even openlijk op tafel als extractie, en besluit beide met hetzelfde bewijs.

  4. Ondersteunt je platform en volwassenheid van bereikbaarheidsdienst de stijl die je voorstelt werkelijk, en kun je de specifieke gaten benoemen voordat je je vastlegt? Microservices, meshes en gebeurtenisgedreven ruggengraten leveren hun voordelen alleen bovenop volwassen CI/CD, gedistribueerde tracing, servicediscovery en een cultuur van bereikbaarheidsdienst die kan redeneren over gedeeltelijk falen. Een grote organisatie neigt ertoe de doelstijl in een architectuurforum te kiezen en het ontbrekende platform later te ontdekken, zodra tientallen services al in productie zijn en elk incident uren kost om te diagnosticeren. Weeg de aantrekkingskracht van onafhankelijke deployment en schaling af tegen de nuchtere vraag wie het om 3 uur ‘s nachts draait: dezelfde splitsing die teams vrijmaakt om parallel op te leveren vermenigvuldigt ook de faalwijzen die elk team moet begrijpen. Neem een eerlijke inventaris mee naar de discussie: huidige deploymentfrequentie, gemiddelde hersteltijd, of je tracing over servicegrenzen hebt en hoeveel services één team realistisch kan beheren. Voeg in omgevingen van onderneming en overheid de aanbestedings- en wervingsdoorlooptijden toe voor de platformcapaciteiten die je mist, want een stijl die een mesh en een platformteam aanneemt die je niet hebt gefinancierd is een plan om een onondersteunbaar landschap te draaien.

  5. Voor welke delen van het domein is een volledig event-sourced auditspoor een wettelijke noodzaak in plaats van een gemak, en wie heeft de bevoegdheid te beslissen? Event sourcing en CQRS kopen je een perfecte, reconstrueerbare geschiedenis en leesmodellen die zelf schalen, maar kosten je gebeurtenisversionering, projectieherbouw en redeneren over uiteindelijke consistentie voor de levensduur van het systeem. Toegepast op een domein dat het auditspoor nooit nodig had is die complexiteit pure belasting. Onthouden aan een domein waar “hoe kwamen we bij deze waarde?” een juridische vraag is, is de afwezigheid ervan een compliancefalen. De concurrerende overwegingen zijn controleerbaarheid en querieschaalbaarheid aan de ene kant en debugmoeilijkheid en cognitieve belasting voor ontwikkelaars aan de andere, dus de beslissing hoort bij mensen die zowel de regelgevende verplichting als de operationele last begrijpen, niet bij wie het meest enthousiast is over het patroon. Neem de specifieke wettelijke of contractuele bewaar- en reconstructie-eisen mee, het verwachte gebeurtenisvolume en een eerlijke schatting van het versie- en projectiewerk. Noem in financiën, belasting en overheid, waar het reconstrueren van een beslissing jaren later een wettelijke plicht kan zijn, de verantwoordelijke eigenaar die goedkeurt dat een gegeven afgebakende context wel of niet een onveranderlijk gebeurtenissenlog nodig heeft.

  6. Hoe voorkom je dat de modulaire monoliet erodeert zodat latere extractie goedkoop blijft, en wat dwingt de grenzen af? De hele zaak voor beginnen met een modulaire monoliet rust op de belofte dat heldere interne grenzen latere serviceextractie betaalbaar maken, maar die grenzen vervallen stilletjes zodra een deadline één module verleidt in de data van een andere te grijpen. Voor een groot team met veel bijdragers zullen goede bedoelingen en codereview alleen de lijn niet houden. Zonder afdwingmechanisme wordt de monoliet stilletjes de big ball of mud die de stijl moest vermijden. Weeg de wrijving van afgedwongen afhankelijkheidsregels en modulinterfaces af tegen de kosten van jaren later ontdekken dat geen grens echt is en elke extractie het ontwarren van gedeelde toestand betekent. Neem bewijs mee: worden modulegrenzen afgedwongen door buildtooling, statische analyse of pakketstructuur, of zijn het slechts gedocumenteerde conventies die de laatste zes samenvoegingen negeerden? Behandel in langlevende systemen van onderneming en overheid die strikte wijzigingsbeheersing en meerdere frameworkgeneraties moeten overleven grenshandhaving als controleerbare beheersmaatregel, zodat de optie om later te distribueren er een is die je werkelijk hebt behouden in plaats van een waarvan je aanneemt dat je haar nog hebt.

Sectorperspectief

Startup. Kies standaard een enkele modulaire monoliet en weersta de trek van microservices, omdat je schaarsste middel engineeringaandacht is en een zwerm services operationele belasting is die je je niet kunt veroorloven voor product-marktfit. Houd heldere modulegrenzen zodat je later kunt extraheren, en grijp naar serverless waar schalen naar nul en betalen per gebruik passen bij je piekerige, laag-basislijn belasting. Splits precies één ding alleen wanneer een concrete drijfveer verschijnt, zoals een stootgewijze notificatieverzender, en nooit eerder.

Kleinbedrijf. Zonder platformteam en met een krap budget geef je de voorkeur aan een monoliet of een handvol grofmazige services op een beheerd platform, en koop je gehoste infrastructuur in plaats van zelf meshes, tracing en servicediscovery te bouwen. Weeg serverless en beheerde databases af als manier om helemaal geen servers te draaien, en wees op je hoede voor een gedistribueerd ontwerp waarvan je de operationele last niemand hebt om te dragen. De juiste architectuur is degene die een of twee mensen werkelijk kunnen deployen, observeren en herstellen.

Grote onderneming. Het echte probleem is veel teams en de wet van Conway: lijn grofmazige services uit op afgebakende contexten en teameigenaarschap, en investeer bewust in het platform (CI/CD, tracing, mesh en servicediscovery) dat distributie veilig maakt. Standaardiseer gateway-, BFF- en interne cleane-architectuurpatronen zodat groepen ophouden ze opnieuw uit te vinden, en bestuur extractie en herconsolidatie als op bewijs gebaseerde portfoliobeslissingen in plaats van lokale voorkeur. Begroot de operationele kosten van elke splitsing expliciet, want op jouw schaal is het falen van de gedistribueerde monoliet duur en traag terug te draaien.

Overheid. Lange systeemlevensduur, strikte wijzigingsbeheersing, aanbestedingscycli en controleerbaarheid sturen de keuze: geef de voorkeur aan stijlen met expliciete, inspecteerbare grenzen en duurzame contracten die leveranciers en frameworkgeneraties overleven. Event sourcing verdient haar complexiteit waar het reconstrueren van een burgergerichte beslissing een wettelijke plicht is, dus gebruik haar bewust voor kerngrootboeken en houd cleane architectuur binnen elke service om regels te isoleren die met elke begroting veranderen. Behandel overdraagbaarheid en uitstappen uit propriëtaire serverless- of leveranciersplatformen als aanbestedingseisen, niet als bijgedachte.

Voorbeelden

Startup. Een startup van vier personen die een planningsproduct bouwt voelt de druk met microservices te beginnen omdat een concurrent erover blogde, maar weerstaat. Ze leveren één modulaire monoliet op met heldere interne grenzen (planning, facturering, notificaties) als aparte modules in één deployable, zodat één engineer het geheel lokaal kan draaien en een release één push is. Naarmate het product tractie vindt, wordt alleen de notificatieverzender, die onder stootgewijze belasting uitwaaiert naar e-mail en sms, in een eigen service getrokken. Ze erven niets van de operationele belasting van een dozijn services terwijl ze nog op zoek zijn naar product-marktfit.

Grote onderneming. Een groot e-commercebedrijf begint als modulaire monoliet. Naarmate het verkeer groeit en teams zich vermenigvuldigen, trekt het de domeinen met de hoogste belasting en de meest onafhankelijke evolutie (catalogus, winkelwagen, checkout en zoeken) in aparte services, elk met eigen data. Checkout zendt gebeurtenissen uit die voorraad, fulfilment en analytics consumeren via een gebeurtenissenruggengraat, zodat nieuwe consumenten (fraudedetectie, loyaliteit) kunnen aanhaken zonder checkout aan te raken. Een API-gateway handelt authenticatie en ratelimiting af, en een BFF past payloads aan voor mobiel. De overige domeinen met lager verkeer blijven in de monoliet, wat onnodige fragmentatie vermijdt.

Overheid. Een belastingdienst bouwt een beoordelingsplatform op event sourcing voor het kerngrootboek, omdat elke wijziging in de aansprakelijkheid van een belastingplichtige jarenlang reconstrueerbaar en juridisch controleerbaar moet zijn. Commando’s (aangifte indienen, betaling toepassen, correctie uitgeven) produceren onveranderlijke gebeurtenissen, en leesmodellen projecteren huidige saldi voor ambtenaren en burgers. CQRS laat de publieksgerichte querykant zelfstandig schalen voor het piekseizoen van aangiftes zonder de schrijfkant in gevaar te brengen. Binnenin volgt elke service cleane architectuur, zodat de beoordelingsregels, die met elke begroting veranderen, geïsoleerd blijven van de persistentie- en berichtentechnologie.

Zakelijke onderbouwing: motivatie, ROI en TCO

Het geld dat op het spel staat bij een stijlkeuze is enorm, omdat de beslissing duur is om terug te draaien. Neem je microservices te vroeg aan en je blaast de total cost of ownership op door platformopbouw, gedupliceerde infrastructuur, gedistribueerd debuggen en een zwaardere operationele last: kosten die levenslang bij het systeem blijven. Weiger je een werkelijk overbelaste monoliet te splitsen en je begrenst de leveringsdoorvoer: teams staan achter een gedeelde release in de rij en elke wijziging brengt het hele systeem in gevaar. Het ROI-gesprek gaat in werkelijkheid over het afstemmen van operationele uitgaven op organisatorische behoefte.

Maak de zaak voor het bestuur in termen van doorvoer en risico, niet technologie. Onafhankelijke deploybaarheid betekent meer teams die parallel opleveren en kortere doorlooptijden: meetbare bedrijfssnelheid. Foutisolatie betekent minder totale storingen en een kleinere schadezone: meetbare beschikbaarheid en reputatiebescherming. Maar wees even eerlijk over de platforminvestering die elke stijl vraagt: een mesh, tracing en CI/CD-volwassenheid zijn voorwaarden, geen optionele extra’s, en hun kosten horen in de TCO. Voor veel organisaties is het goedkoopste pad nu een goed gemodulariseerde monoliet, met heldere interne grenzen die latere extractie goedkoop maken. Dat koopt je de optie te distribueren zonder ervoor te betalen voordat je het nodig hebt.

Antipatronen en valkuilen

  • Gedistribueerde monoliet. Services die samen moeten worden gedeployd en een database delen: alle kosten van distributie, geen van de onafhankelijkheid.
  • Nanoservices. Services zo fijnmazig dat orkestratie en netwerkoverhead het werk dat ze doen in de schaduw stellen.
  • Microservices zonder platform. Splitsen voordat je CI/CD, tracing en volwassenheid van bereikbaarheidsdienst hebt. Faalwijzen vermenigvuldigen zich.
  • Entiteitsservices. Splitsen op databasetabel (“Gebruikersservice”, “Bestelservice”) in plaats van op bedrijfsvermogen, wat voor elke bewerking praatzieke aanroepen tussen services afdwingt.
  • Event sourcing overal. Het toepassen op domeinen die geen auditspoor nodig hebben, de complexiteitsbelasting betalend zonder voordeel.
  • Gateway als monoliet. Bedrijfslogica in de API-gateway stoppen en zo een centraal knelpunt herscheppen.
  • Aan het framework gekoppelde kern. Bedrijfslogica verstrengeld met het web- of ORM-framework (object-relational mapping), wat zowel testen als technologieverandering pijnlijk maakt.

Volwassenheidsmodel

  • Niveau 1: Initiëren. Stijl wordt gekozen door mode of toeval. Je hebt één verstrengelde monoliet of een toevallige gedistribueerde rommel, grenzen volgen technische lagen of geschiedenis in plaats van het domein, en splitsingen gebeuren reactief wanneer iets breekt.
  • Niveau 2: Ontwikkelen. Sommige teams trekken bewuste modulegrenzen binnen de monoliet of zetten een paar grofmazige services op, en sommige dwarsdoorsnijdende zorgen worden consistent afgehandeld. De praktijk is ongelijk: de ene groep lijnt services uit op afgebakende contexten terwijl een andere nog op databasetabel splitst, en extractie blijft ad hoc.
  • Niveau 3: Standaardiseren. Een gedocumenteerde aanpak wordt over de organisatie gehandhaafd: services lijnen uit op afgebakende contexten en bezitten hun data, gateway- en BFF-patronen worden gebruikt waar passend, interne cleane of hexagonale gelaagdheid is de standaard en elke splitsing vraagt een benoemde drijfveer. Modulegrenzen worden door tooling afgedwongen, niet alleen door conventie.
  • Niveau 4: Beheersen. Stijlbeslissingen worden gemeten en gestuurd aan de hand van uitgangswaarden. Je volgt deploymentfrequentie en doorlooptijd per service, gemiddelde hersteltijd, hoeveel services samen moeten deployen voor een typische wijziging en netwerkhoplatentie, en vergelijkt de kosten van elke splitsing met de onafhankelijkheid die ze moest kopen. Bewijs, geen voorkeur, bepaalt of een grens overleeft, en afdrijving naar een gedistribueerde monoliet wordt door statistieken gevangen in plaats van door een storing.
  • Niveau 5: Orkestreren. Architectuur is geïntegreerd met organisatieontwerp en wordt continu aangepast. Een volwassen platform (CI/CD, tracing en mesh waar gerechtvaardigd) maakt zowel distributie als herconsolidatie goedkoop, teams extraheren routinematig wanneer een drijfveer verschijnt en vouwen services terug wanneer er een verdwijnt, en stijlkeuzes worden herbalanceerd naarmate teamtopologie, belasting en risicobeeld over het hele landschap verschuiven.

Ideeën voor discussie

  1. Waar in je systeem is een monoliet werkelijk een sterkte, en waar een echt knelpunt?
  2. Welke concrete drijfveer zou het extraheren van je volgende service rechtvaardigen, en kun je haar benoemen voordat je bouwt?
  3. Heeft je organisatie de operationele volwassenheid die microservices eisen? Wat ontbreekt er?
  4. Voor welke delen van je domein is een volledig event-sourced auditspoor een wettelijke of zakelijke noodzaak tegenover een prettige extra?
  5. Hoe goed weerspiegelen je huidige servicegrenzen je teamgrenzen, en helpt of schaadt die afstemming?
  6. Als je volgend jaar je webframework of database zou moeten wijzigen, hoeveel van je bedrijfslogica zou je moeten herschrijven?

Belangrijkste inzichten

  • Kies de architectuurstijl uit echte krachten (teamgrootte, domein, belasting, operationele volwassenheid), niet uit mode.
  • Een modulaire monoliet is de juiste standaard voor de meeste systemen. Extraheer services alleen met een concrete drijfveer en langs de lijnen van afgebakende contexten.
  • Microservices ruilen operationele en cognitieve complexiteit in voor onafhankelijke deployment, schaling en foutisolatie. Ze vereisen een volwassen platform.
  • Gebeurtenisgedreven, CQRS en event sourcing bieden ontkoppeling en controleerbaarheid ten koste van uiteindelijke consistentie en versioneringscomplexiteit. Neem ze bewust aan.
  • Gateways, BFF’s en meshes temmen landschappen met veel services maar voegen gewicht toe. Introduceer ze wanneer schaal het eist, niet eerder.
  • Pas hexagonale/cleane architectuur toe binnen elke service om waardevolle bedrijfslogica testbaar en duurzaam te houden over technologieverandering.

Referenties en verder lezen

  • Sam Newman, Building Microservices and Monolith to Microservices
  • Chris Richardson, Microservices Patterns
  • Eric Evans, Domain-Driven Design
  • Vaughn Vernon, Implementing Domain-Driven Design
  • Robert C. Martin, Clean Architecture
  • Alistair Cockburn, “Hexagonal Architecture (Ports and Adapters)”
  • Gregor Hohpe and Bobby Woolf, Enterprise Integration Patterns
  • Martin Fowler, Patterns of Enterprise Application Architecture (and articles on CQRS and Event Sourcing)
  • Matthew Skelton and Manuel Pais, Team Topologies