Platform

O que é idempotência e como lidar com webhooks duplicados?

Idempotência faz uma operação repetida ter o mesmo efeito de uma única operação, então lide com webhooks duplicados sem repetir o trabalho deles.

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 cabeçalho Idempotency-Key para cada tentativa de uma operação lógica API.

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 mutáveis 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 mutável 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çãoResposta e recuperação
Mesma chave e solicitação após conclusãoA resposta armazenada, com Idempotency-Replay: true.
Chave concluída reutilizada para outra solicitação409 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ção409 com E01004, significando solicitação em andamento. Aguarde brevemente e tente novamente.
Chave excede 255 caracteres400 com E01002, significando entrada inválida. 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.

O bloqueio de uma operação não concluída expira em trinta segundos. Esse limite permite que outra solicitação prossiga após uma operação abandonada. Ele não determina se um efeito colateral já ocorreu.

O Bird não armazena uma resposta 5xx para reprodução. Tente novamente um erro de servidor ou timeout com a mesma chave para que um sucesso registrado ainda possa ser reutilizado.

Uma rejeição por validação ou regra de negócio libera a chave. Você pode corrigir essa solicitação rejeitada e tentar novamente com a mesma chave porque nenhuma resposta concluída foi 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 tentativa mantém o mesmo cabeçalho webhook-id, que identifica o evento. Uma reprodução de uma entrega perdida 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.

  1. Verifique a solicitação, depois insira seu identificador e job na mesma transação.
  2. Retorne 2xx após o commit dessa transação, para que o Bird possa parar de tentar novamente.
  3. 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.

Se o armazenamento de deduplicação do Bird estiver indisponível, as solicitações prosseguem sem ele. Mantenha uma proteção no nível de negócio onde repetir uma ação seria prejudicial.

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

  1. 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.

  2. Solicitações rejeitadas podem liberar suas chaves.

    Erros de validação e de regra de negócio não deixam uma resposta concluída, permitindo uma nova tentativa corrigida com a mesma chave.

  3. 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.

  4. A deduplicação tem limites.

    As solicitações prosseguem se o armazenamento de deduplicação estiver indisponível. Mantenha ações repetidas toleráveis também na sua aplicação.

Construa na mesma rede.

Uma chave de API de teste é sua imediatamente. A produção é desbloqueada quando adicionar um método de pagamento e verificar um remetente.

Sua próxima ideia.
Pronta para conectar.