17 juli 2025
Ronald Bakker
Sinds september 2023 werkt Qualogy bij de Belastingdienst aan een mooie, uitdagende opdracht: het ontwikkelen van een nieuwe REST-service voor het opslaan van alle online ingevulde formulieren. En formulieren worden volop ingevuld bij de Belastingdienst.
Vooral in maart en april is het extra druk, omdat dan miljoenen Nederlanders hun aangifte inkomstenbelasting doen.
Kortom, we werken in een interessante en dynamische omgeving, waar de systemen tegen een flinke hoeveelheid requests bestand moeten zijn.
Bij de keuze voor een architectuur voor de nieuwe REST service speelden een aantal zaken een belangrijke rol:
- Er moet rekening gehouden worden met een toekomstige database migratie
- De service moet uitbreidbaar zijn met nieuwe interfaces, zoals REST en Kafka koppelingen
- Schaalbaarheid is erg belangrijk om de drukte in de maanden maart en april goed op te kunnen vangen
- Uiteraard was de code kwaliteit en test coverage erg belangrijk
Deze eisen brachten ons al snel op het idee om een Hexagonal Architecture te gebruiken.
Wat is een Hexagonal Architecture?
Hexagonal Architecture (ook wel bekend als Ports and Adapters) is een softwarearchitectuurstijl die je helpt om de domeinlogica van je applicatie te scheiden van externe zaken zoals databases, gebruikersinterfaces, API’s of messaging-systemen.
Stel je je applicatie voor als een zeshoek (vandaar de naam). In het midden zit je businesslogica (de "core" of het "domein"), volledig onafhankelijk van de buitenwereld. Rondom die kern zitten "poorten" (ports) – abstracties van hoe je met de buitenwereld communiceert. Aan die poorten koppel je via "adapters" de echte technologieën zoals webservers, databases of externe API’s.
Je applicatie bestaat dan grofweg uit drie delen:
- Domein: bevat de echte businesslogica: regels, use cases, entities. Dit deel heeft geen kennis van infrastructuur.
- Ports: Een set van interfaces die definiëren wat de core nodig heeft of aanbiedt: bijv. FormRepository, NotificationSender.
- Adapters: Vormen de implementaties van de Ports. Hier worden externe technologieën gekoppeld aan de poorten: bijvoorbeeld een DB2-implementatie van FormRepository of een Kafka interface die notificaties verstuurt.
Wat betekent dit voor de ontwikkelaars?
Niet elke programmeur in het team had ervaring met een Hexagonal architectuur, maar de overgang bleek voor iedereen soepel te verlopen. Er zitten namelijk ook voor de programmeur verschillende voordelen aan het gebruik van deze architectuur.
De architectuur geeft bijvoorbeeld duidelijke structuur en verantwoordelijkheid. Programmeurs weten precies waar ze welke code moeten schrijven (business logica versus infrastructuur). Dit geldt uiteraard ook voor de code reviews, omdat je ook weet waar je code wijzigingen verwacht voor een user story.
Het is ook makkelijker om unit tests te schrijven. De business logica is namelijk geïsoleerd van externe systemen, waardoor je unit-tests kunt schrijven zonder mocks van databases of HTTP.
Daarnaast is de architectuur flexibel en makkelijk uitbreidbaar. Programmeurs kunnen nieuwe adapters (bijv. Kafka naast REST) toevoegen zonder de business logica aan te passen. Ook de vereiste migratie naar een nieuwe database kan uitgevoerd worden zonder enige impact op de business logica.
Een nadeel is wel dat de architectuur soms wat meer code en boilerplate vereist. Iedere overgang van een adapter laag naar de domein laag en weer terug vereist mappers. Dit kost in het begin wat meer tijd, maar loont op de lange termijn.
ArchUnit
De architectuur werkt alleen goed als iedereen zich aan de scheiding van lagen houdt. Discipline en consistentie is daarom belangrijk. "Snelle hacks", zoals direct een DB-query in je use case, zijn verleidelijk maar ondermijnen het hele model.
Om de architectuur te bewaken maken we gebruik van ArchUnit, een Java-bibliotheek waarmee je architecturale regels als code kunt definiëren en automatisch kunt testen. In plaats van alleen vertrouwen op discipline van de programmeurs, kun je met ArchUnit afdwingen dat je architectuur wordt nageleefd.
De architecturale afspraken worden nu gedefinieerd in Java unit tests, net zoals de gewone tests. Op deze manier detecteren we schendingen van afspraken omtrent de architectuur (zoals “de domein laag mag geen toegang hebben tot de adapters”).
Succesvolle aangiftecampagne
Ons project had afgelopen lente een hoogtepunt toen onze service voor het eerst werd ingezet voor het aangifteformulier voor inkomstenbelasting. In maart en april heeft de Belastingdienst 10,5 miljoen aangiftes van particulieren en ondernemers ontvangen. Deze periode verliep ook dit jaar weer zonder noemenswaardige problemen.
Bij iedere klik in het formulier wordt een aanroep naar onze service gedaan om het formulier op te slaan. Tijdens deze twee maanden heeft de service ruim 531 miljoen requests afgehandeld.
Al met al een succesvolle periode en ook de komende periode hebben we nog diverse technische uitdagingen. Maar met onze Hexagonal Architecture hebben we vertrouwen de uitdagingen aan te kunnen!