Sign inGet Started

Idempotência

Use Idempotency-Key quando uma conexão com falha deixar você sem saber se sua requisição foi bem-sucedida. A garantia é de aceitação exatamente uma vez: novas tentativas com a mesma chave e requisição idêntica precisam resultar em uma única operação aceita dentro da janela de retenção de 3 horas, mesmo que você tenha perdido a resposta original.

Como funciona

A idempotência é opt-in. Adicione um cabeçalho Idempotency-Key a uma requisição POST, PATCH, PUT ou DELETE suportada. Requisições sem ele são processadas normalmente, sem deduplicação. Requisições GET ignoram o cabeçalho.

Na API do cliente, mutações com escopo de espaço de trabalho e de organização suportam o replay de resposta descrito abaixo. Operações restritas a usuário, sem escopo, não autenticadas e streams não passam por ele. Operações com um contrato de replay separado definem seu comportamento na respectiva página de referência. Por exemplo, Criar uma chamada de voz retém o snapshot de aceitação original para tentativas correspondentes quando você fornece uma chave.

Os SDKs geram uma chave para cada chamada de mutação e a reutilizam em tentativas automáticas, incluindo criação de chamadas. Você não precisa fornecer uma chave para tentativas automáticas do SDK. Forneça a sua própria quando uma operação pretendida abrange chamadas SDK separadas, como uma nova tentativa após reiniciar sua aplicação. Estes exemplos mostram esse caso.

await bird.email.send(
  {
    from: "hello@yourdomain.com",
    to: ["delivered@messagebird.dev"],
    subject: "Welcome!",
    html: "<p>Thanks for signing up.</p>",
  },
  { idempotencyKey: "welcome-user/usr_abc123" },
);

Uma chave é qualquer string não vazia com até 255 caracteres. Um valor de cabeçalho vazio ignora a deduplicação. O formato recomendado é uma chave determinística derivada das suas próprias entidades, <event-type>/<entity-id> (por exemplo welcome-user/usr_abc123), para que tentativas entre reinícios de processo compartilhem a mesma chave; um UUID aleatório por operação lógica também funciona. Os SDKs Bird geram uma chave UUID automaticamente para cada requisição de mutação e a reutilizam em suas tentativas internas.

As chaves têm escopo no seu espaço de trabalho, ou na sua organização em endpoints de nível organizacional. Uma resposta concluída é mantida por 3 horas; uma nova tentativa após essa janela pode ser processada como uma requisição nova. Se o resultado da operação original for desconhecido após a expiração, mantenha-a como não resolvida e reconcilie-a antes de enviar novamente.

Replays

Uma nova tentativa correspondente dentro de três horas precisa resultar na operação original. Quando a resposta dela está retida, API retorna o mesmo código de status e o mesmo corpo sem aceitar outra operação. Respostas reproduzidas incluem um cabeçalho extra para que você possa diferenciá-las de um processamento novo:

Exemplo de código
HTTP/1.1 202 Accepted
Idempotency-Replay: true

Respostas retidas podem incluir rejeições 4xx. Use uma nova chave ao corrigir uma requisição: se a rejeição foi retida, uma nova tentativa sem alteração a reproduz, e uma requisição alterada retorna 409 E01005 IdempotencyKeyReuse. Respostas 5xx não são retidas como respostas concluídas. A garantia de aceitação exatamente uma vez também cobre novas tentativas após esses erros.

Modos de falha

CenárioResposta
Mesma chave, mesma requisição, resposta original retida dentro da janela de retençãoResposta reproduzida com Idempotency-Replay: true
Mesma chave, corpo da requisição ou endpoint diferente409, E01005 IdempotencyKeyReuse
Mesma chave, requisição original ainda em andamento409, E01004 RequestInProgress
Chave com mais de 255 caracteres em um endpoint que declara o header422, E01001 ValidationError
Proteção de idempotência indisponível antes da execução503, E01033 IdempotencyUnavailable; esta tentativa não é executada

Reutilizar uma chave concluída com uma requisição diferente é tratado como um bug do cliente: Bird retorna 409 imediatamente em vez de entregar silenciosamente uma resposta que não corresponde ao que você enviou. Gere uma nova chave para a nova requisição. A comparação abrange o método, o endpoint, os parâmetros de path e query e o corpo bruto da requisição, incluindo espaços em branco JSON. Uploads multipart comparam nomes das partes, nomes de arquivos e conteúdos; boundaries e a ordem das partes não afetam o replay.

RequestInProgress significa que uma requisição concorrente com a mesma chave ainda não terminou. Normalmente isso acontece quando um timeout agressivo no lado do cliente dispara uma nova tentativa enquanto a primeira ainda está sendo processada. Aguarde brevemente e tente novamente com a mesma chave e a mesma requisição. Veja Errors para a resposta de erro que envolve esses erros.

O que não é armazenado em cache

Respostas 5xx não são retidas como respostas concluídas. Tente novamente dentro de três horas com backoff limitado, a mesma chave e a requisição idêntica. A garantia de aceitação exatamente uma vez se aplica mesmo quando a resposta original foi perdida.

Se a proteção de idempotência estiver indisponível antes da execução, API retorna 503 E01033 IdempotencyUnavailable sem executar esta tentativa. Mantenha a chave sempre que tentar novamente. Este erro não descreve o resultado de uma tentativa anterior com a mesma chave.

Orientações práticas

  • Gere uma chave por operação lógica e reutilize-a em toda tentativa HTTP dessa operação.
  • Em erros de rede, timeouts e 5xx, tente novamente dentro de três horas com backoff exponencial limitado, mantendo a chave e a requisição idêntica.
  • Quando as novas tentativas se esgotarem ou a retenção expirar, mantenha o resultado desconhecido como não resolvido. Faça a reconciliação antes de enviar outra operação, seja com a chave antiga ou com uma nova.
  • Para envios de mensagens, verifique o status da mensagem para confirmar a entrega após a aceitação.
  • Trate 409 IdempotencyKeyReuse como um bug na sua geração de chaves. Não tente novamente.
  • Chaves são opcionais em mutações. Use uma quando precisar de proteção para tentar novamente com segurança; omita-a em requisições GET.

Próximos passos

Continue com a documentação, guias e exemplos sobre este tópico.