Inhoudsopgave
De meeste integraties tussen systemen werken op één van twee manieren: polling (waarbij je systeem regelmatig vraagt “is er iets nieuws?”) of webhooks (waarbij het andere systeem jouw systeem actief op de hoogte stelt zodra er iets gebeurt). Polling is eenvoudig maar inefficiënt: je doet honderden verzoeken voor elk verzoek dat daadwerkelijk iets teruggeeft. Webhooks draaien dat om en zijn daarmee de betere keuze voor realtime automatisering. Ze zijn echter iets complexer om correct in te richten, en wie die complexiteit onderschat loopt tegen subtiele problemen aan.
Hoe een webhook werkt
Een webhook is in essentie een HTTP POST-verzoek dat een extern systeem naar jouw server stuurt op het moment dat er een gebeurtenis plaatsvindt. Een betaling wordt voltooid in Stripe, een pull request wordt geopend in GitHub, een formulier wordt ingestuurd in Typeform: al die systemen kunnen op dat moment een verzoek sturen naar een URL die jij opgeeft, met de relevante data in de body. Jouw server ontvangt dat verzoek, verwerkt de data en voert de gewenste actie uit. Simpel in concept, maar de details (beveiliging, betrouwbaarheid, volgorde) vragen aandacht.
Beveiliging van webhook endpoints
Een webhook endpoint is een publiek toegankelijke URL die commando’s van buitenaf accepteert, wat het een potentieel aanvalspunt maakt. Verificeer daarom altijd de afzender van een webhook. De meeste platforms (Stripe, GitHub, Shopify) sturen een handtekening mee in de headers die je kunt valideren met een gedeeld geheim. Bereken de verwachte handtekening aan de hand van de request body en het geheim, en vergelijk die met de meegestuurde handtekening. Wijs verzoeken af die niet overeenkomen. Sla het gedeelde geheim op als omgevingsvariabele, nooit hardcoded in je code.
Snel antwoorden, later verwerken
Een veelgemaakte fout bij webhook verwerking is de volledige verwerking uitvoeren binnen het HTTP-verzoek zelf. Als die verwerking lang duurt (een database-query, een externe API-call, een berekening) riskeer je een timeout aan de kant van de verzender, die het verzoek dan opnieuw stuurt. Het patroon dat dit oplost is eenvoudig: stuur direct een 200 OK terug zodra het verzoek binnenkomt, en zet de verwerking in een wachtrij (via tools zoals Redis, RabbitMQ of een simpele database-tabel) die je asynchroon verwerkt. Zo is je endpoint snel en betrouwbaar.
Omgaan met duplicaten en volgorde
Webhook-systemen garanderen doorgaans “at least once delivery”: een verzoek wordt minstens één keer verstuurd, maar soms vaker als de eerste poging geen bevestiging krijgt. Je endpoint moet daarom idempotent zijn: hetzelfde verzoek twee keer verwerken mag niet tot dubbele acties leiden. Gebruik een uniek event-ID (dat de meeste platforms meesturen) om bij te houden welke events al zijn verwerkt. Volgorde is ook niet gegarandeerd: events kunnen in een andere volgorde binnenkomen dan ze zijn verstuurd, dus vertrouw nooit op een vaste volgorde tenzij het platform dat expliciet belooft.
Lokaal testen met webhooks
Webhooks testen is lastiger dan gewone API-calls omdat de externe service een publiek toegankelijke URL nodig heeft. Lokaal draaien op localhost werkt niet zonder hulpmiddelen. Tools zoals ngrok en Cloudflare Tunnel lossen dat op door een tijdelijke publieke URL aan te maken die verkeer doorstuurt naar je lokale server. Combineer dat met de testfunctionaliteit die de meeste platforms bieden (Stripe en GitHub hebben bijvoorbeeld ingebouwde webhook simulators) en je kunt je volledige verwerkingslogica lokaal testen zonder een liveomgeving nodig te hebben.