Een verbroken verbinding kan je onzeker laten of een verzendverzoek is geslaagd. Een verloren bevestiging kan er ook voor zorgen dat een webhookafzender een event aflevert dat je applicatie al heeft opgeslagen.
Deze fouten gebeuren in tegengestelde richtingen. Bird kan een herhaald API-verzoek herkennen aan de hand van een sleutel die je meegeeft. Je webhookontvanger heeft een eigen registratie nodig van events die al geaccepteerd zijn.
Hoe probeer ik een verzending veilig opnieuw?
Hergebruik dezelfde Idempotency-Key-header voor elke poging van één logische API-bewerking.
Je kiest de sleutel zelf, maximaal 255 tekens, en behoudt deze bij retries. Een stabiele waarde zoals welcome-user/usr_abc123 kan één welkomstberichtbewerking identificeren nadat je proces opnieuw is gestart.
De header is van toepassing op muterende verzoeken zoals POST, PATCH en DELETE. Een verzoek zonder sleutel wordt verwerkt zonder deze deduplicatie. GET negeert de header omdat het lezen van de resource al veilig herhaalbaar is.
Bird retourneert het opgeslagen antwoord voor een overeenkomend voltooid verzoek, inclusief de oorspronkelijke status en body. Het antwoord bevat Idempotency-Replay: true, zodat je dat hergebruik in je logs kunt herkennen.
De idempotentiegids beschrijft een standaard van drie uur voor het venster van het voltooide antwoord. Een retry na afloop daarvan kan als een nieuwe bewerking worden uitgevoerd. Vertrouw niet permanent op die sleutel om dubbele verzendingen te voorkomen.
Bird-SDK's genereren een sleutel voor een mutatie en hergebruiken die bij hun interne retries. De Bird CLI genereert ook een sleutel voor een muterend verzoek wanneer er geen aanwezig is. Stel --idempotency-key expliciet in wanneer afzonderlijke commando-aanroepen dezelfde bewerking moeten delen.
Gebruik voor SMTP-indiening de X-Bird-Idempotency-Key-berichtheader. Hiermee kan een opnieuw ingediende indiening dezelfde bewerking identificeren.
Wat gebeurt er als ik een sleutel verkeerd hergebruik?
Bird weigert conflicterend sleutelgebruik in plaats van een antwoord voor een andere bewerking te retourneren.
| Situatie | Antwoord en herstel |
|---|---|
| Dezelfde sleutel en hetzelfde verzoek na voltooiing | Het opgeslagen antwoord, met Idempotency-Replay: true. |
| Voltooide sleutel hergebruikt voor een ander verzoek | 409 met E01005, wat hergebruik van de idempotentiesleutel betekent. Pas de sleutel aan voordat je opnieuw probeert. |
| Een ander verzoek met die sleutel is nog bezig | 409 met E01004, wat verzoek in uitvoering betekent. Wacht kort en probeer opnieuw. |
| Sleutel langer dan 255 tekens | 400 met E01002, wat ongeldige invoer betekent. Verkort de sleutel. |
De vergelijking omvat de methode, het endpoint, padparameters, querystring en body. Bij JSON verandert het wijzigen van witruimte de verzoekidentiteit, dus bewaar de oorspronkelijke body bij retries.
De vergrendeling op een onvoltooide bewerking verloopt binnen dertig seconden. Die limiet laat een ander verzoek doorgaan na een afgebroken bewerking. Het stelt niet vast of er al een neveneffect is opgetreden.
Bird slaat geen 5xx-antwoord op voor hergebruik. Probeer een serverfout of time-out opnieuw met dezelfde sleutel, zodat een geregistreerd succes alsnog hergebruikt kan worden.
Een validatie- of bedrijfsregelafwijzing geeft de sleutel vrij. Je kunt dat afgewezen verzoek corrigeren en opnieuw proberen met dezelfde sleutel, omdat er geen voltooid antwoord is bewaard.
Waarom ontvang ik dezelfde webhook twee keer?
Bird kan een event opnieuw proberen dat je ontvanger al heeft opgeslagen als het geen succesvol antwoord ontvangt.
Een ontvanger kan een event opslaan vlak voordat de verbinding wegvalt. Bird ziet geen succesvolle bevestiging en probeert opnieuw, ook al heeft de ontvanger het event al.
Elke retry behoudt dezelfde webhook-id-header, die het event identificeert. Een replay van een gemiste aflevering behoudt die identifier ook, zodat beide als hetzelfde event herkend kunnen worden.
Hoe maak ik mijn handler idempotent?
Sla elke webhook-id op onder een unieke databaseconstraint voordat je het werk van het event inplant.
Controleren of een rij al bestaat voordat je invoegt laat een race condition open: twee gelijktijdige verzoeken kunnen allebei geen rij zien. Laat de database dubbele identifiers afwijzen.
Sla de identifier en de taak op in dezelfde transactie. Dit voorkomt dat een identifier wordt geregistreerd zonder dat er werk in de wachtrij staat.
- Verifieer het verzoek en voeg vervolgens de identifier en taak in binnen dezelfde transactie.
- Retourneer
2xxnadat die transactie is gecommit, zodat Bird kan stoppen met opnieuw proberen. - Verwerk de opgeslagen taak in een worker die zijn eigen acties veilig kan herhalen.
Retourneer bij een dubbele identifier die al gecommit is een succes zonder een nieuwe taak aan te maken. Retourneer bij een mislukte transactie een fout zodat Bird opnieuw probeert.
Houd traag werk buiten de ontvanger, want wachten erop kan ervoor zorgen dat het verzoek een time-out krijgt. Een worker kan opnieuw proberen om redenen die los staan van webhookaflevering, dus alleen de ontvanger beschermen is onvoldoende.
Events kunnen ook in de verkeerde volgorde aankomen. Vergelijk eventtijden in timestamp voordat je nieuwere status overschrijft. Mislukte webhook-retries bevat het voorbeeld met gedeeltelijke kosten.
Waar moet je niet op vertrouwen?
Ga er niet van uit dat deduplicatie van verzoeken dubbele neveneffecten onmogelijk maakt.
Als de deduplicatieopslag van Bird niet beschikbaar is, gaan verzoeken zonder deduplicatie door. Houd een beveiliging op bedrijfsniveau aan waar het herhalen van een actie schadelijk zou zijn.
Op dezelfde manier onderscheidt webhook-id herhaalde afleveringen van één event. Afzonderlijke events hebben afzonderlijke identifiers. Je applicatie beslist nog steeds of die events het herhalen van dezelfde actie rechtvaardigen.
Idempotentie documenteert het retry-gedrag van API. Webhooks behandelt de afzonderlijke afleveringsgaranties die je ontvanger afhandelt.
Kort gezegd
API-retries en webhook-retries vereisen verschillende registraties.
Hergebruik Idempotency-Key voor een verzoek aan Bird. Je ontvanger slaat webhook-id op om een event te herkennen dat al geaccepteerd is.
Afgewezen verzoeken kunnen hun sleutels vrijgeven.
Validatie- en bedrijfsregelfouten laten geen voltooid antwoord achter, waardoor je gecorrigeerd opnieuw kunt proberen met dezelfde sleutel.
Een voltooide sleutel kan niet voor andere verzoeken worden gebruikt.
Een gewijzigde JSON-body of -endpoint kan een 409-conflict opleveren. Pas de sleutel aan in plaats van dat conflict ongewijzigd opnieuw te proberen.
Deduplicatie heeft grenzen.
Verzoeken gaan door als de deduplicatieopslag niet beschikbaar is. Zorg dat herhaalde acties ook in je eigen applicatie geen schade aanrichten.