Reexecutar uma requisicao sem duplo efeito
A idempotência permite reexecutar uma requisicao POST sem temer um duplo efeito. Um cliente que perde a resposta por timeout pode retentar com a mesma chave de idempotência, é a API retorna a resposta armazenada em vez de executar o handler novamente. CaptainDNS segue a convencao Stripe, com janela de validade de 24 horas.
Por que usar idempotência
As redes não sao confiaveis. Um cliente pode:
- Enviar uma requisicao que tem sucesso no servidor mas cuja resposta se perde.
- Cair no meio de um retry automático.
- Ver um timeout no load balancer mesmo que a API já tenha processado.
Sem idempotência, você escolhe entre não reenviar (é perder operações legitimas) ou reenviar cegamente (é executar varias vezes). A idempotência oferece uma terceira via: reenviar com segurança.
Como usar
Adicione um header Idempotency-Key a sua requisicao POST:
POST /public/v1/deliverability/score HTTP/1.1
Host: api.captaindns.com
Authorization: Bearer cdns_live_a3f2XK7mN9QrVtZ4yP1sH6eL8cF2dB5aR3gW7kJxM
Content-Type: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
{"email":"contact@captaindns.com"}
A chave deve ser uma string opaca entre 10 é 255 caracteres. UUIDv4 sao ideais.
Comportamento no servidor
Na primeira requisicao, o middleware calcula o sha256 do body, grava o registro (api_key_id, idempotency_key, request_hash) após o sucesso é captura status é body da resposta.
Na segunda requisicao com a mesma chave:
- O middleware encontra o registro existente.
- Se o hash do novo body corresponde: replay. A resposta armazenada é retornada com
X-Idempotent-Replay: true. - Se o hash difere: conflito. A API retorna
409 IDEMPOTENCY_CONFLICT.
Um replay consome zero créditos é não dispara o handler subjacente.
Janela de validade
Os registros vivem 24 horas. Apos esse prazo, um job de purge os remove é uma chave reutilizada executa o handler normalmente.
Metodos cobertos
A idempotência só se aplica a métodos mutativos ou custosos. Na pratica, todos os endpoints publicos CaptainDNS sao POST. O header Idempotency-Key é opcional.
Conflitos
Um 409 IDEMPOTENCY_CONFLICT é disparado quando uma chave é reutilizada com body diferente. Para evitar:
- Calcule a chave antes de serializar o body.
- Não misture chamadas diferentes sob a mesma chave.
- Se seu framework reordena as chaves JSON, fixe a ordem manualmente.
Exemplos de uso
Retry após timeout de rede
idempotencyKey = uuid()
for attempt in 1..3:
try:
response = post(url, body, headers={"Idempotency-Key": idempotencyKey})
return response
except TimeoutError:
sleep(2 * attempt)
raise
Deduplicacao em fila de jobs
job = fetch_next_job()
idempotencyKey = hash(job.id)
response = post(url, job.payload, headers={"Idempotency-Key": idempotencyKey})
mark_job_done(job.id, response)
Batch com dedupe no servidor
for domain in domains:
idempotencyKey = "batch-" + run_id + "-" + domain
post(url, {"domain": domain}, headers={"Idempotency-Key": idempotencyKey})
Limitacoes
- 24 h de armazenamento: alem disso, o replay não é mais possível.
- Escopo por chave API: duas chaves diferentes com o mesmo valor não colidem.
- Sem coordenacao entre servidores: varios backends devem coordenar as chaves.
- Identidade estrita do body: um espaco a mais quebra o hash.
Proximos passos
Siga com os códigos de erro para entender como reagir a 409 IDEMPOTENCY_CONFLICT, ou consulte a referência OpenAPI.