Schrijver: Max van Deursen, Software Engineer
Bij een nieuw project begin je als consumer en provider samen met het omschrijven van het contract van je communicatie. In mijn vorige blogs gebruikte ik dit contract, de OpenAPI Specification (OAS), om te testen of de integratie klopt, vanuit zowel een consumer als provider perspectief. Met behulp van Specmatic kan dit al voordat de API live staat!
Na verloop van tijd wil je nieuwe functionaliteit toevoegen. Daarom wil je het opgestelde contract wijzigen. Hoe zorg je ervoor dat deze wijzigingen geen roet in het eten gooien en de live applicaties blijven draaien. En hoe blijven de bestaande tests up-to-date?
In deze blog kijk ik naar de functionaliteit die Specmatic biedt om de specificaties te centraal te beheren. Daarnaast laat ik zien hoe Specmatic wijzigingen kan beoordelen, zodat je geen brekende veranderingen in het contract doorvoert. Deze combinatie zorgt ervoor dat je specificaties up-to-date en passend blijven.
Het voorbeeld
Net zoals in mijn vorige blogs gebruik ik het voorbeeld van het winkelmandje van een webshop. De API is vastgelegd in CartAPI_v1.yaml, waarmee je een winkelmandje kan aanmaken, vullen, en opvragen. De voorbeeldcode voor deze blog heb ik op GitHub gezet, zodat je deze blog kan volgen en kan gebruiken voor je eigen implementatie.
Beheer vanuit centrale repositories
Als je een OAS wilt aanpassen, moet je alle plekken waar deze opgeslagen staat nagaan. Als je een plek vergeet, kunnen de testen van consumers en providers gaan uiteenlopen, met vergaande gevolgen: fouten in de integratie. Dit is iets wat contract testing juist wil voorkomen. Daarom is een centrale plek waar deze specificaties opgeslagen staan belangrijk. Specmatic noemt dit de Central Contract Repository en biedt de functionaliteit om OAS uit jouw centrale Git repository op te halen en te gebruiken. Door de configuratie aan te passen kan Specmatic deze OAS op de centrale plek gebruiken.
In het voorbeeld refereert de Specmatic configuratie (specmatic.yaml) van de consumer nu naar het centrale geplaatste contract:
Ditzelfde geldt voor de specmatic.yaml van de provider:
Specmatic kijkt naar het opgegeven pad in de beschreven URL om de OAS in te laden. Hierdoor zijn er geen kopieën meer op verschillende plekken en heb je de contracten gecentraliseerd.
Waarom wijzigingen valideren
Met deze nieuwe opzet kun je de OAS makkelijk wijzigen vanuit een centrale plek. Denk nu aan het volgende scenario: je wilt nieuwe functionaliteit toevoegen, terwijl er al een bestaande versie live staat. Hiervoor zijn wijzigingen in de specificatie nodig. Je maakt deze aanpassingen en zet deze in de centrale repository en… de tests van zowel jouw consumer als provider falen. Hoe kan dat nou?!
De wijzigingen die je hebt gedaan zijn niet backwards compatible. Backwards compatibility betekent dat consumers zowel de oude als de nieuwe versie zonder aanpassingen kunnen gebruiken. Dat is een goed streven en zorgt ervoor dat je alleen bepaalde wijzigingen op een gebruikte specificatie kan doorvoeren:
Alle andere wijzigingen op een bestaand contract kunnen niet worden gedaan zonder aanpassingen vanuit bestaande gebruikers. Als zo’n wijziging onvermijdelijk is, kan je een nieuw contract opstellen. Hierna kan je als provider het oude en het nieuwe contract ondersteunen. Jouw consumers gaan na verloop van tijd over op de nieuwe versie, waarna de oude versie kan worden uitgefaseerd. Dit proces is bewerkelijk, dus is het van belang dat je de samenwerking vroeg opzoekt om het contract goed op te stellen.
Wijzigingen valideren met Specmatic
Het is best lastig om telkens je wijzigingen op backwards compatibility te toetsen. Gelukkig heeft Specmatic ook functionaliteit om dit te testen met het commando backward-compatibility-check. Voordat je wijzigingen op een contract doorvoert, verifieert dit commando dat al jouw wijzigingen inderdaad backwards compatible zijn. Het voorbeeld gebruikt GitHub Actions om deze verificatie te doen. Deze Actions voeren stappen automatisch uit in het GitHub platform uit te voeren. De Action definitie in het voorbeeld, backward-compatibility.yml, kijkt of de wijzigingen backwards compatible zijn bij elke voorgestelde wijziging:
Op regel 13 wordt de Specmatic Docker image ingezet om alle stappen van de Action uit te voeren. Op regel 22 wordt de backward-compatibility-check uitgevoerd om de wijzigingen met de master branch te vergelijken. Deze Action is alleen succesvol als alle wijzigingen backwards compatible zijn.
Afdwingen van backwards compatibility
Om ervoor te zorgen dat je geen wijzigingen doorvoert die backwards incompatible zijn, mist er nog een puzzelstukje: het blokkeren van deze verkeerde wijzigingen. GitHub biedt functionaliteit om het doorvoeren (mergen) alleen mogelijk te maken als alle status checks succesvol zijn. In het voorbeeld wordt dit gedaan door het doorvoeren afhankelijk te maken van een succesvolle backward-compatibility check:
Als je GitHub zo configureert, kan je alleen nog backwards compatible wijzigingen doorvoeren.
De validatie in actie
In het voorbeeld zijn er twee voorgestelde wijzigingen (Pull Requests). Het eerste voorstel voegt een nieuw verplicht veld toe om een winkelmandje aan te maken, genaamd otherId:
Dit is een wijziging die niet backwards compatible is, omdat de consumer geen weet heeft van otherId. Gelukkig detecteert Specmatic deze wijziging en door het afdwingen kan de wijziging niet worden doorgevoerd:
Als je doorklikt op de uitgevoerde Action, zie je dat Specmatic de wijziging ziet en afkeurt:
Het tweede voorbeeld voegt de naam van het product toe als je de inhoud van een winkelwagentje ophaalt:
Deze wijziging is backwards compatible en de check vanuit Specmatic is ook succesvol:
Deze wijziging is backwards compatible en de check vanuit Specmatic is ook succesvol:
Met deze opzet zorg je ervoor dat alle wijzigingen bewijsbaar backwards compatible zijn, voordat deze doorgevoerd zijn. Alle bestaande consumers kunnen hierdoor vertrouwen op een up-to-date specificatie, waarop wijzigingen veilig worden doorgevoerd.
Tot slot
In deze blogreeks heb je met behulp van Specmatic Contract Testing opgezet. Aan de hand van de OAS test je de consumer met de smart mock server. Diezelfde OAS gebruik je om de provider implementatie van de OAS te testen. En in deze blog heb je het beheer van deze OAS verder uitgediept. Dit samen geeft een opstelling waarmee jij zeker bent dat jouw consumer en provider doen wat ze beloven. Ook kan je vroegtijdig ingrijpen en verrassingen voorkomen in de communicatie tussen de twee applicaties. Hiermee zorg je dat het samenwerken aan API’s betrouwbaarder en sneller verloopt, zonder verrassingen bij livegang. Gebruik deze vier blogs als opzet voor de toepassing van Specmatic om dit ook binnen jouw project en organisatie waar te maken.
Overzicht blogreeks
19 augustus 2025 – Contract Testing: Integratieproblemen vroeg opgelost
20 oktober 2025 – Contract Testing voor consumers: aan de slag met Specmatic’s Smart Mocks
23 december 2025 – Contract Testing voor providers; test je API met Specmatic
4 maart 2026 – Contract Testing: Beheer en updaten van specificaties