Platform

Cos'è l'idempotenza e come gestisco i webhook duplicati?

L'idempotenza fa sì che un'operazione ripetuta produca lo stesso effetto di un'unica operazione: gestisci i webhook duplicati senza ripetere il loro lavoro.

Una connessione interrotta può lasciarti nell'incertezza se una richiesta di invio sia riuscita. Un acknowledgment perso può anche far sì che un mittente di webhook consegni un evento che la tua applicazione ha già memorizzato.

Questi errori avvengono in direzioni opposte. Bird può riconoscere una richiesta API ripetuta tramite una chiave che fornisci tu. Il tuo receiver di webhook ha bisogno di un proprio registro degli eventi già accettati.

Come posso riprovare un invio in sicurezza?

Riutilizza lo stesso header Idempotency-Key per ogni tentativo di una singola operazione logica API.

Scegli tu la chiave, fino a 255 caratteri, e la mantieni tra i tentativi. Un valore stabile come welcome-user/usr_abc123 può identificare un'operazione di messaggio di benvenuto anche dopo il riavvio del processo.

L'header si applica alle richieste mutanti come POST, PATCH e DELETE. Una richiesta senza chiave viene elaborata senza questa deduplicazione. GET ignora l'header perché leggere la risorsa è già sicuro da ripetere.

Bird restituisce la risposta memorizzata per una richiesta completata corrispondente, inclusi status e body originali. La risposta contiene Idempotency-Replay: true, così puoi identificare quel riutilizzo nei tuoi log.

La guida all'idempotenza documenta un valore predefinito di tre ore per la finestra della risposta completata. Un tentativo dopo la scadenza può essere eseguito come nuova operazione. Non fare affidamento su quella chiave in modo permanente per prevenire invii duplicati.

Gli SDK Bird generano una chiave per una mutazione e la riutilizzano nei propri tentativi interni. Il Bird CLI genera anch'esso una chiave per una richiesta mutante quando è assente. Imposta --idempotency-key esplicitamente quando invocazioni di comandi separate devono condividere la stessa operazione.

Per l'invio SMTP, usa l'header del messaggio X-Bird-Idempotency-Key. Questo permette a un invio riprovato di identificare la stessa operazione.

Cosa succede se riutilizzo una chiave in modo errato?

Bird rifiuta un uso conflittuale della chiave anziché restituire una risposta per un'operazione diversa.

SituazioneRisposta e recupero
Stessa chiave e richiesta dopo il completamentoLa risposta memorizzata, con Idempotency-Replay: true.
Chiave completata riutilizzata per una richiesta diversa409 con E01005, che indica riutilizzo della chiave di idempotenza. Correggi la chiave prima di riprovare.
Un'altra richiesta con quella chiave è ancora in esecuzione409 con E01004, che indica richiesta in corso. Attendi brevemente e riprova.
La chiave supera i 255 caratteri400 con E01002, che indica input non valido. Accorcia la chiave.

Il confronto include metodo, endpoint, parametri del percorso, query string e body. Per JSON, modificare gli spazi cambia l'identità della richiesta, quindi preserva il body originale durante i tentativi.

Il lock su un'operazione non completata scade entro trenta secondi. Questo limite consente a un'altra richiesta di procedere dopo un'operazione abbandonata. Non stabilisce se un effetto collaterale si sia già verificato.

Bird non memorizza una risposta 5xx per il replay. Riprova un errore del server o un timeout con la stessa chiave, così un successo già registrato può ancora essere riutilizzato.

Un rifiuto per validazione o regola di business rilascia la chiave. Puoi correggere quella richiesta rifiutata e riprovare con la stessa chiave perché nessuna risposta completata è stata conservata.

Perché ricevo lo stesso webhook due volte?

Bird può riprovare un evento che il tuo receiver ha già memorizzato se non riceve una risposta positiva.

Un receiver può memorizzare un evento subito prima che la sua connessione si interrompa. Bird non vede alcun acknowledgment positivo e riprova, anche se il receiver ha già l'evento.

Ogni tentativo mantiene lo stesso header webhook-id, che identifica l'evento. Anche un replay di una consegna mancata mantiene quell'identificatore, quindi entrambi possono essere riconosciuti come lo stesso evento.

Come rendo il mio handler idempotente?

Memorizza ogni webhook-id sotto un vincolo di unicità del database prima di schedulare il lavoro dell'evento.

Verificare l'esistenza di una riga prima di inserirla lascia una race condition: due richieste concorrenti possono entrambe non trovare alcuna riga. Lascia che sia il database a rifiutare gli identificatori duplicati.

Memorizza l'identificatore e il job nella stessa transazione. Questo impedisce che un identificatore venga registrato senza alcun lavoro accodato.

  1. Verifica la richiesta, poi inserisci il suo identificatore e il job nella stessa transazione.
  2. Restituisci 2xx dopo il commit della transazione, così Bird può smettere di riprovare.
  3. Elabora il job memorizzato in un worker che può ripetere in sicurezza le proprie azioni.

Per un identificatore duplicato già committato, restituisci successo senza creare un altro job. Per una transazione fallita, restituisci un errore così Bird riprova.

Tieni il lavoro lento fuori dal receiver perché attenderlo può causare il timeout della richiesta. Un worker può riprovare per motivi non legati alla consegna del webhook, quindi proteggere solo il receiver non è sufficiente.

Gli eventi possono anche arrivare in ordine diverso. Confronta i tempi degli eventi in timestamp prima di sovrascrivere uno stato più recente. Tentativi di webhook falliti include l'esempio del costo parziale.

Su cosa non dovrei fare affidamento?

Non dare per scontato che la deduplicazione delle richieste renda impossibili gli effetti collaterali duplicati.

Se lo store di deduplicazione di Bird non è disponibile, le richieste procedono senza di esso. Mantieni una protezione a livello di business dove ripetere un'azione sarebbe dannoso.

Analogamente, webhook-id distingue le consegne ripetute di uno stesso evento. Eventi separati hanno identificatori separati. La tua applicazione decide comunque se quegli eventi giustificano la ripetizione della stessa azione.

Idempotenza documenta il comportamento dei tentativi di API. Webhook copre le garanzie di consegna separate che il tuo receiver gestisce.

In breve

  1. I tentativi verso API e i tentativi webhook richiedono record diversi.

    Riutilizza Idempotency-Key per una richiesta a Bird. Il tuo receiver memorizza webhook-id per riconoscere un evento già accettato.

  2. Le richieste rifiutate possono rilasciare le loro chiavi.

    Gli errori di validazione e di regole di business non lasciano una risposta completata, consentendo un nuovo tentativo corretto con la stessa chiave.

  3. Una chiave completata non può identificare richieste diverse.

    Un body o un endpoint JSON modificato può produrre un conflitto 409. Correggi la chiave anziché riprovare lo stesso conflitto invariato.

  4. La deduplicazione ha dei limiti.

    Le richieste procedono se lo store di deduplicazione non è disponibile. Mantieni le azioni ripetute gestibili anche nella tua applicazione.

Costruisci sulla stessa rete.

Una chiave API di test è subito tua. L'accesso alla produzione si sblocca quando aggiungi un metodo di pagamento e verifichi un mittente.

La tua prossima idea.
Pronta a partire.