Eine Anfrage ohne doppelte Wirkung wiederholen
Idempotenz erlaubt es, eine POST-Anfrage zu wiederholen, ohne eine doppelte Seitenwirkung zu riskieren. Ein Client, der die Antwort durch ein Timeout verliert, kann mit demselben Idempotency-Key erneut senden und erhält die gespeicherte Antwort, anstatt den Handler erneut auszuführen. CaptainDNS folgt der Stripe-Konvention mit einem 24-Stunden-Fenster.
Warum Idempotenz
Netzwerke sind unzuverlässig. Ein Client kann:
- eine Anfrage senden, die serverseitig erfolgreich ist, deren Antwort jedoch verloren geht,
- mitten im automatischen Retry abstürzen,
- ein Timeout am Load Balancer sehen, obwohl die API die Anfrage bereits verarbeitet hat.
Ohne Idempotenz musst du zwischen zwei schlechten Optionen wählen: nicht wiederholen und legitime Operationen verlieren, oder blind wiederholen und dieselbe Operation mehrfach ausführen. Idempotenz bietet dir einen dritten Weg: sicheres Wiederholen.
Verwendung
Füge einen Idempotency-Key-Header zu deiner POST-Anfrage hinzu:
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"}
Der Key muss ein opaker String mit 1 bis 255 druckbaren ASCII-Zeichen ohne Leerzeichen sein. UUID v4 oder ULID sind als Best Practice empfohlen (ausreichende Entropie, statistisch unmögliche Kollisionen), aber jeder clientseitig eindeutige Identifier funktioniert.
Serverseitiges Verhalten
Beim ersten Aufruf berechnet die Idempotenz-Middleware den sha256 des Body, speichert nach Erfolg den Datensatz (api_key_id, idempotency_key, request_hash) und erfasst Status und Body der Antwort.
Beim zweiten Aufruf mit demselben Schlüssel:
- Die Middleware findet den vorhandenen Datensatz.
- Stimmt der neue Body-Hash mit dem gespeicherten überein, wird die gespeicherte Antwort zurückgegeben, mit
X-Idempotent-Replay: true. - Bei abweichendem Hash liefert die API
409 IDEMPOTENCY_CONFLICT.
Ein Replay verbraucht null Credits und ruft den zugrundeliegenden Handler nicht auf.
Gültigkeitsfenster
Idempotenz-Einträge leben 24 Stunden. Danach werden sie durch einen Purge-Job entfernt, und ein wiederverwendeter Schlüssel ruft den Handler ganz normal auf.
Erfasste Methoden
Idempotenz gilt nur für mutierende oder teure Methoden. In der Praxis sind alle öffentlichen CaptainDNS-Endpunkte POST-Anfragen. Der Idempotency-Key-Header ist optional.
Konflikte
Ein 409 IDEMPOTENCY_CONFLICT entsteht, wenn ein Schlüssel mit abweichendem Body wiederverwendet wird. Vorbeugung:
- Berechne den Idempotency-Key vor dem Serialisieren des Body.
- Mische keine verschiedenen Aufrufe unter demselben Key.
- Wenn dein Framework JSON-Schlüssel umsortiert, fixiere die Reihenfolge.
Verwendungsbeispiele
Retry nach Netzwerk-Timeout
idempotencyKey = uuid()
for attempt in 1..3:
try:
response = post(url, body, headers={"Idempotency-Key": idempotencyKey})
return response
except TimeoutError:
sleep(2 * attempt)
raise
Deduplizierung in einer Job-Queue
job = fetch_next_job()
idempotencyKey = hash(job.id)
response = post(url, job.payload, headers={"Idempotency-Key": idempotencyKey})
mark_job_done(job.id, response)
Batch mit serverseitiger Dedupe
for domain in domains:
idempotencyKey = "batch-" + run_id + "-" + domain
post(url, {"domain": domain}, headers={"Idempotency-Key": idempotencyKey})
Einschränkungen
- 24 h Speicherlimit: darüber hinaus ist kein Replay mehr möglich.
- Scope pro API-Schlüssel: derselbe Schlüssel mit zwei verschiedenen API-Schlüsseln kollidiert nicht.
- Keine Serverübergreifende Koordination: mehrere Backends müssen die Keys untereinander abstimmen.
- Strikte Body-Identität: ein zusätzliches Leerzeichen bricht den Hash.
Nächste Schritte
Weiter mit dem Fehlerhandbuch, um auf 409 IDEMPOTENCY_CONFLICT richtig zu reagieren, oder der OpenAPI-Referenz.