Was ist Idempotenz? HTTP-Methoden, API-Keys, Beispiele
Idempotenz: N-fache Operation = einmalige, kritisch für sichere Retries in verteilten APIs. GET/PUT/DELETE sind idempotent, POST nicht.
Was ist Idempotenz?
Idempotenz ist eine Eigenschaft einer Operation, bei der die mehrfache Ausführung dasselbe Ergebnis produziert wie die einmalige Ausführung. Mathematisch: f(x) = f(f(x)) = f(f(f(x))). In API- und verteilten Systemen-Kontexten kann eine idempotente Operation sicher wiederholt werden ohne unbeabsichtigte Nebenwirkungen, kritisch wenn Netzwerke unzuverlässig sind und Sie nicht wissen, ob Ihr vorheriger Request erfolgreich war.
Das klassische Beispiel ist ein Aufzugsknopf: einmal drücken oder zehnmal drücken produziert dasselbe Ergebnis (der Aufzug kommt einmal). Vergleichen Sie mit dem Belasten einer Kreditkarte: zehnmal "Bezahlen" drücken ohne Idempotenz produziert zehn Belastungen. Idempotenz-Design macht Systeme sicher zu retry'en.
Idempotenz in HTTP/REST APIs
Die HTTP-Spezifikation (RFC 7231) definiert, welche Methoden idempotent sind:
| HTTP-Methode | Idempotent? | Typische Verwendung |
|---|---|---|
| GET | Ja | Resource lesen. N-fach aufgerufen liefert dieselben Daten, keine State-Änderung |
| HEAD | Ja | Wie GET aber nur Headers |
| PUT | Ja | Resource ersetzen. N-fach aufgerufen lässt die Resource im selben End-State |
| DELETE | Ja | Resource entfernen. N-fach aufgerufen: erste Mal entfernt sie, nachfolgende sind No-Ops |
| OPTIONS | Ja | Erlaubte Methoden discovern |
| TRACE | Ja | Diagnostischer Loopback |
| POST | Nein | Resource erstellen. N-fach aufgerufen erstellt typischerweise N Resources |
| PATCH | Nein (default) | Partielles Update, hängt von Semantik ab |
Beachten Sie: idempotent bedeutet NICHT "dieselbe Response zurückgeben". DELETE returnt 204 beim ersten Mal und 404 bei nachfolgenden Calls, verschiedene Responses, aber der Server-State ist identisch. Die Eigenschaft betrifft den End-State, nicht Response-Equivalenz.
Beispiele: idempotent vs nicht-idempotent
Idempotente Operationen
PUT /users/123 {"name": "Alice"}, setzt den User-Namen auf Alice. 10x aufgerufen lässt den Namen Alice.DELETE /sessions/abc, entfernt Session abc. 10x aufgerufen resultiert weiterhin in keiner Session abc.GET /products/42, liest Produkt 42.PUT /flags/feature-x {"enabled": true}. Feature-Flag-Toggle nach Absolutwert.
Nicht-idempotente Operationen
POST /orders {...}, erstellt eine neue Order. 10x aufgerufen erstellt 10 Orders.POST /charges {...}, belastet eine Kreditkarte. 10x aufgerufen belastet 10x.PATCH /counters/x {"increment": 1}, inkrementiert um 1 bei jedem Call.POST /emails {"to": "..."}, sendet eine E-Mail. 10 Calls = 10 E-Mails.
Warum Idempotenz wichtig ist
In einer Single-Machine-Transactional-Welt würden Sie nie dieselbe Operation zweimal aufrufen. Aber moderne Systeme sind verteilt, und das ändert alles:
- Netzwerk-Fehler. Ihr Client sendet einen Request, bekommt keine Response. Erfolgreich? Sie wissen es nicht. Idempotent → sicher retry'en.
- Timeouts. Selbes Problem. Der Server kann den Request verarbeitet haben nachdem der Client aufgegeben hat.
- Verteilte Retries. Service Meshes, Load Balancers und SDKs retry'en auto. Sicher nur wenn upstream idempotent.
- Queue-basierte Architekturen. Messages können mehr als einmal geliefert werden (at-least-once). Consumers müssen Duplikate idempotent handhaben.
- Nutzer-Verhalten. Nutzer doppelklicken Submit-Buttons, refresh'en Pages mitten im Request.
Idempotenz-Keys
Für natürlich nicht-idempotente Operationen wie Order-Erstellung oder Karten-Belastung ist das Standard-Pattern der Idempotenz-Key: ein client-generierter eindeutiger Identifier (typischerweise UUID), gesendet mit jedem Request. Der Server speichert das Ergebnis nach diesem ID und returnt dasselbe Ergebnis bei nachfolgenden Requests mit demselben Key.
POST /charges
Idempotency-Key: 8e0a4e6b-1b8e-4e3a-b9f7-5e1d3f9c4b8a
{
"amount": 5000,
"currency": "USD"
}Der erste Call verarbeitet die Belastung und speichert das Ergebnis. Nachfolgende Calls mit demselben Key returnen das gespeicherte Ergebnis ohne Re-Processing. Der Key läuft typischerweise nach einem Window ab (z.B. 24 Stunden).
Idempotenz-Keys server-seitig implementieren
- Request mit Idempotenz-Key empfangen.
- Key-Store (Redis, DB-Tabelle) auf existierenden Eintrag prüfen.
- Wenn gefunden: gespeicherte Response returnen (keine Side-Effects).
- Wenn nicht gefunden: Lock auf Key acquiren, Request verarbeiten, Response speichern, Lock releasen.
- In-Flight-Requests handhaben: wenn ein Duplikat ankommt während der erste verarbeitet wird, entweder warten oder 409 Conflict returnen.
- Keys nach dem vereinbarten Window expiren.
Real-World-Beispiele
- Stripe. Die Referenz-Implementierung. Jeder state-ändernde API-Endpoint akzeptiert einen
Idempotency-Key-Header. - AWS SDK. Viele AWS-APIs nutzen ClientToken-Parameter (Idempotenz-Keys). EC2 RunInstances, RDS CreateDBInstance.
- PayPal, Square, Adyen. Alle Payment-Processors nutzen Idempotenz-Keys.
- HTTP/2 + retry-aware Clients. Moderne HTTP-Clients retry'en automatisch idempotente Methoden bei Connection-Failures.
Häufige Fallstricke
- PATCH als immer idempotent behandeln. Hängt von Semantik ab.
- Side-Effects jenseits der Datenbank. Wenn Ihr "idempotenter" Endpoint eine E-Mail sendet, sendet zweimaliges Aufrufen zwei E-Mails.
- Idempotenz-Keys ohne Expiry. Jeden Key forever zu speichern verursacht unbegrenztes Wachstum. TTLs setzen.
- Race Conditions bei konkurrierenden Retries. Locks oder Database-Constraints nutzen.
- Idempotenz mit Safety verwechseln. Safe = keine Side-Effects (GET). Idempotent = N Calls = 1 Call's Effect. PUT/DELETE sind idempotent aber nicht safe.
Idempotenz in Load Testing
- POST-Endpoints akkumulieren State. Ein 1.000-VU-Lasttest gegen POST /orders erstellt 1.000 × Duration × RPS Orders. Cleanup danach.
- Idempotenz-Key-Reuse cached die Response. Wenn Ihr Script denselben Key über VUs reuse't, bekommen alle VUs die gecachte erste Response.
- Eindeutige Idempotenz-Keys pro VU/Iteration generieren.
- Den Idempotenz-Mechanismus selbst testen.
FAQ: Idempotenz
Ist GET immer idempotent?
Per HTTP-Spec ja. GET sollte nie State modifizieren. In der Praxis missbrauchen manche APIs GET für State-Änderungen.
Ist PATCH idempotent?
Hängt von der Operation ab. PATCH {set: x} ist idempotent. PATCH {increment: 1} nicht.
Was ist der Unterschied zwischen Idempotenz und Safety?
Safe bedeutet keine beobachtbaren Side-Effects (GET, HEAD, OPTIONS). Idempotent bedeutet N Calls = 1 Call's End-State. PUT und DELETE sind idempotent aber nicht safe.
Wie mache ich POST idempotent?
Idempotenz-Key nutzen, eine client-generierte UUID gesendet mit jedem Request.
Was ist eine gute Idempotenz-Key-TTL?
Stripe nutzt 24 Stunden. Für high-throughput APIs reicht 1 Stunde. Für Payment-APIs gibt 7-30 Tage mehr Retry-Toleranz.
Gilt Idempotenz für gRPC und GraphQL?
Ja. gRPC-Method-Definitionen können Idempotenz-Level spezifizieren. GraphQL Query-Operations sind idempotent per Konvention; Mutations brauchen explizites Idempotenz-Design.
Probieren Sie LoadFocus für Idempotenz-Testing at Scale
Wenn Sie einen Idempotenz-Mechanismus designen und unter Last verifizieren wollen (konkurrierende Retries, Race Conditions, Key-Expiry), läuft LoadFocus JMeter- und k6-Scripts aus 25+ Cloud-Regionen mit bis zu 12.500 VUs. Registrieren bei loadfocus.com/signup, keine Kreditkarte, und führen Sie Ihren ersten Idempotenz-Stresstest in unter 5 Minuten aus.
Verwandte LoadFocus-Tools
Setze dieses Konzept mit LoadFocus in die Praxis um, derselben Plattform, die alles antreibt, was du gerade gelesen hast.