Ir para o conteúdo principal

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:

  1. O middleware encontra o registro existente.
  2. Se o hash do novo body corresponde: replay. A resposta armazenada é retornada com X-Idempotent-Replay: true.
  3. 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.