Uma conexão interrompida pode deixar você sem saber se uma solicitação de envio foi bem-sucedida. Uma confirmação perdida também pode fazer um emissor de webhooks entregar um evento que sua aplicação já armazenou.
Essas falhas acontecem em direções opostas. O Bird pode reconhecer uma solicitação API repetida usando uma chave que você fornece. Seu receptor de webhooks precisa de seu próprio registro dos eventos que já aceitou.
Como faço para tentar novamente um envio com segurança?
Reutilize o mesmo Idempotency-Key e uma solicitação idêntica em cada nova tentativa. A garantia é a aceitação exatamente uma vez: novas tentativas correspondentes dentro de três horas devem resultar em uma única operação aceita, mesmo que você tenha perdido a resposta dela.
Você escolhe a chave, com até 255 caracteres, e a mantém entre tentativas. Um valor estável como welcome-user/usr_abc123 pode identificar uma operação de mensagem de boas-vindas após o reinício do seu processo.
O cabeçalho se aplica a solicitações de mutação como POST, PATCH e DELETE. Uma solicitação sem chave é processada sem essa deduplicação. GET ignora o cabeçalho porque ler o recurso já é seguro para repetição.
O Bird retorna a resposta armazenada para uma solicitação concluída correspondente, incluindo seu status e corpo originais. A resposta carrega Idempotency-Replay: true, para que você possa identificar essa reutilização nos seus logs.
O guia de idempotência documenta um padrão de três horas para a janela de resposta concluída. Uma nova tentativa após esse período pode ser executada como uma nova operação. Não dependa dessa chave permanentemente para evitar envios duplicados.
Os SDKs do Bird geram uma chave para uma mutação e a reutilizam em suas tentativas internas. O Bird CLI também gera uma chave para uma solicitação de mutação quando não há uma presente. Defina --idempotency-key explicitamente quando invocações de comando separadas precisarem compartilhar a mesma operação.
Para envio via SMTP, use o cabeçalho de mensagem X-Bird-Idempotency-Key. Isso permite que um envio repetido identifique a mesma operação.
O que acontece se eu reutilizar uma chave incorretamente?
O Bird rejeita o uso conflitante da chave em vez de retornar uma resposta para uma operação diferente.
| Situação | Resposta e recuperação |
|---|---|
| Mesma chave e solicitação, resposta retida | A resposta armazenada dentro do período de retenção, com Idempotency-Replay: true. |
| Chave concluída reutilizada para outra solicitação | 409 com E01005, significando reutilização de chave de idempotência. Corrija a chave antes de tentar novamente. |
| Outra solicitação com essa chave ainda em execução | 409 com E01004, significando solicitação em andamento. Aguarde brevemente e tente novamente. |
| Chave excede 255 caracteres | 422 com E01001 nos endpoints que declaram o cabeçalho. Encurte a chave. |
A comparação inclui o método, endpoint, parâmetros de caminho, query string e corpo. Para JSON, alterar espaços em branco altera a identidade da solicitação, então preserve o corpo original durante as tentativas.
Se a solicitação original ainda estiver em execução, aguarde antes de tentar novamente. Mantenha a mesma chave e a mesma solicitação para que a nova tentativa identifique a operação original.
O API não retém uma resposta 5xx como resposta concluída. Tente novamente após um timeout ou erro de servidor com backoff limitado, a mesma chave e uma solicitação idêntica dentro de três horas. A garantia de aceitação exatamente uma vez também cobre uma resposta perdida.
Uma rejeição 4xx pode ser retida. Use uma nova chave para uma solicitação corrigida: uma nova tentativa sem alterações reproduz a rejeição retida, e uma entrada alterada entra em conflito com essa chave retida.
Por que recebo o mesmo webhook duas vezes?
O Bird pode tentar novamente um evento que seu receptor já armazenou se não receber uma resposta bem-sucedida.
Um receptor pode armazenar um evento logo antes de sua conexão cair. O Bird não vê confirmação bem-sucedida e tenta novamente, mesmo que o receptor já tenha o evento.
Cada nova tentativa mantém o mesmo cabeçalho webhook-id, que identifica o evento. Uma reprodução de uma entrega com falha também mantém esse identificador, então ambas podem ser reconhecidas como o mesmo evento.
Como torno meu handler idempotente?
Armazene cada webhook-id sob uma restrição única no banco de dados antes de agendar o trabalho do evento.
Verificar se já existe uma linha antes de inserir deixa uma condição de corrida: duas solicitações simultâneas podem ambas não ver nenhuma linha. Deixe o banco de dados rejeitar identificadores duplicados.
Armazene o identificador e o job na mesma transação. Isso evita que um identificador seja registrado sem nenhum trabalho enfileirado.
- Verifique a solicitação, depois insira seu identificador e job na mesma transação.
- Retorne
2xxapós o commit dessa transação, para que o Bird possa parar de tentar novamente. - Processe o job armazenado em um worker que possa repetir suas próprias ações com segurança.
Para um identificador duplicado já comitado, retorne sucesso sem criar outro job. Para uma transação que falhou, retorne um erro para que o Bird tente novamente.
Mantenha o trabalho lento fora do receptor porque esperar por ele pode fazer a solicitação expirar. Um worker pode tentar novamente por motivos não relacionados à entrega de webhooks, então proteger apenas o receptor é insuficiente.
Os eventos também podem chegar fora de ordem. Compare os horários dos eventos em timestamp antes de sobrescrever um estado mais recente. Tentativas de webhook com falha inclui o exemplo de custo parcial.
No que não devo confiar?
Não presuma que a deduplicação de solicitações torna efeitos colaterais duplicados impossíveis.
Para uma gravação compatível no HTTP, o Bird vincula a chave de idempotência ao espaço de trabalho ou à organização da solicitação. Operações de equipe compatíveis usam, em vez disso, a conta do membro da equipe que executa a ação. Se a proteção estiver indisponível, o Bird retorna 503 E01033 IdempotencyUnavailable antes de executar essa tentativa. Isso não resolve o resultado de uma tentativa anterior. A garantia de aceitação exatamente uma vez cobre novas tentativas correspondentes dentro de três horas. Verifique o status da mensagem para confirmar a entrega. Se as novas tentativas se esgotarem ou a janela expirar, verifique o resultado da operação original antes de enviar novamente.
Da mesma forma, o webhook-id distingue entregas repetidas de um mesmo evento. Eventos distintos têm identificadores distintos. Sua aplicação ainda decide se esses eventos justificam repetir a mesma ação.
Idempotência documenta o comportamento de nova tentativa do API. Webhooks cobre as garantias de entrega separadas que seu receptor gerencia.
Em resumo
Tentativas de reenvio ao API e tentativas de reenvio de webhooks precisam de registros diferentes.
Reutilize Idempotency-Key para uma solicitação ao Bird. Seu receptor armazena webhook-id para reconhecer um evento que já aceitou.
Rejeições também podem ser retidas.
Uma rejeição retida é reproduzida novamente. Uma solicitação corrigida precisa de uma nova chave porque sua entrada é diferente.
Uma chave concluída não pode identificar solicitações diferentes.
Um corpo ou endpoint alterado no JSON pode produzir um conflito 409. Corrija a chave em vez de tentar novamente esse conflito sem alteração.
A deduplicação tem limites.
A garantia do API cobre a aceitação exatamente uma vez de novas tentativas correspondentes dentro de três horas. Seu receptor de webhooks precisa de seus próprios registros duráveis de eventos.