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" },
);client.email.send(
from_="hello@yourdomain.com",
to=["delivered@messagebird.dev"],
subject="Welcome!",
html="<p>Thanks for signing up.</p>",
options={"idempotency_key": "welcome-user/usr_abc123"},
)_, err := client.Email.Send(context.Background(), bird.EmailSendParams{
From: "hello@yourdomain.com",
To: []string{"delivered@messagebird.dev"},
Subject: "Welcome!",
HTML: "<p>Thanks for signing up.</p>",
}, option.WithIdempotencyKey("welcome-user/usr_abc123"))$bird->email->send(
from: 'hello@yourdomain.com',
to: ['delivered@messagebird.dev'],
subject: 'Welcome!',
html: '<p>Thanks for signing up.</p>',
options: new RequestOptions(idempotencyKey: 'welcome-user/usr_abc123'),
);curl -X POST https://us1.platform.bird.com/v1/email/messages \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: welcome-user/usr_abc123" \
-d '{
"from": "hello@yourdomain.com",
"to": ["delivered@messagebird.dev"],
"subject": "Welcome!",
"html": "<p>Thanks for signing up.</p>"
}'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:
HTTP/1.1 202 Accepted
Idempotency-Replay: trueRespostas 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ário | Resposta |
|---|---|
| Mesma chave, mesma requisição, resposta original retida dentro da janela de retenção | Resposta reproduzida com Idempotency-Replay: true |
| Mesma chave, corpo da requisição ou endpoint diferente | 409, E01005 IdempotencyKeyReuse |
| Mesma chave, requisição original ainda em andamento | 409, E01004 RequestInProgress |
| Chave com mais de 255 caracteres em um endpoint que declara o header | 422, E01001 ValidationError |
| Proteção de idempotência indisponível antes da execução | 503, 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 IdempotencyKeyReusecomo 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
- Referência de idempotência API: schemas de header e response-header
- Conceitos de SDK: geração automática de chaves e comportamento de nova tentativa nos SDKs
- Errors: a resposta de erro e o catálogo de códigos
- Envio de e-mail: endpoints de envio e lote
Recursos relacionados
Continue com a documentação, guias e exemplos sobre este tópico.