Reintenta una peticion sin doble efecto
La idempotencia permite reintentar una peticion POST sin temer un doble efecto. Un cliente que pierde la respuesta por timeout puede reintentar con la misma clave de idempotencia, y la API devuelve la respuesta almacenada en lugar de ejecutar de nuevo el handler. CaptainDNS sigue la convencion de Stripe, con una ventana de validez de 24 horas.
Por que usar la idempotencia
Las redes no son fiables. Un cliente puede:
- Enviar una peticion que tiene exito en el servidor pero cuya respuesta se pierde en camino.
- Caer en medio de un reintento automático.
- Ver un timeout en el balanceador cuando la API ya proceso la peticion.
Sin idempotencia, debes elegir entre no reintentar (y perder operaciones legitimas) o reintentar a ciegas (y ejecutar la misma operación varias veces). La idempotencia ofrece una tercera via: reintentar con seguridad.
Como usarla
Anade una cabecera Idempotency-Key a tu peticion 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"}
La clave debe ser una cadena opaca de entre 10 y 255 caracteres. Los UUIDv4 son ideales.
Que pasa en el servidor
En la primera peticion, el middleware calcula el sha256 del body, escribe (api_key_id, idempotency_key, request_hash) tras el exito y captura status y body de la respuesta.
En la segunda peticion con la misma clave:
- El middleware encuentra el registro existente.
- Si el hash del nuevo body coincide: replay. La respuesta almacenada se devuelve tal cual, con
X-Idempotent-Replay: true. - Si el hash difiere: conflicto. La API devuelve
409 IDEMPOTENCY_CONFLICT.
Un replay consume cero créditos y no dispara el handler subyacente.
Ventana de validez
Los registros viven 24 horas. Tras ese plazo, un job de purga los elimina y una clave reutilizada vuelve a ejecutar el handler con normalidad.
Metodos cubiertos
La idempotencia solo aplica a métodos que mutan o son costosos. En la practica, todos los endpoints publicos de CaptainDNS son POST, así que todos son elegibles. La cabecera Idempotency-Key es opcional.
Conflictos
Un 409 IDEMPOTENCY_CONFLICT se dispara cuando una clave se reutiliza con un body diferente. Para evitarlo:
- Calcula la clave antes de serializar el body.
- No mezcles llamadas distintas bajo la misma clave.
- Si tu framework reordena las claves JSON, fija el orden a mano.
Ejemplos de uso
Reintento tras timeout de red
idempotencyKey = uuid()
for attempt in 1..3:
try:
response = post(url, body, headers={"Idempotency-Key": idempotencyKey})
return response
except TimeoutError:
sleep(2 * attempt)
raise
Deduplicacion en cola 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 con dedup en el servidor
for domain in domains:
idempotencyKey = "batch-" + run_id + "-" + domain
post(url, {"domain": domain}, headers={"Idempotency-Key": idempotencyKey})
Limitaciones
- 24 h de almacenamiento: mas alla, el replay ya no es posible.
- Scope por clave API: dos claves distintas con el mismo valor no colisionan.
- Sin coordinacion entre servidores: varios backends deben coordinarse.
- Identidad estricta del body: un espacio extra rompe el hash.
Proximos pasos
Sigue con los códigos de error para entender como reaccionar a 409 IDEMPOTENCY_CONFLICT, o consulta la referencia OpenAPI.