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 1 é 255 caracteres ASCII imprimíveis sem espaco. Os UUID v4 ou ULID continuam recomendados como best practice (entropia suficiente, colisoes estatisticamente impossiveis), mas qualquer identificador unico no lado cliente serve.
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.