Was ist Idempotenz? HTTP-Methoden, Idempotency-Keys, Beispiele
Idempotenz: Eine Operation mehrfach auszuführen ergibt denselben Zustand wie einmal. Welche HTTP-Methoden gelten und wie Keys POST wiederholbar machen.
Was ist Idempotenz?
Eine Operation ist idempotent, wenn ihre mehrfache Ausführung das System im selben Zustand hinterlässt wie die einmalige. Bei HTTP heißt das: Ein Client kann eine Anfrage nach einem Timeout oder Verbindungsabbruch wiederholen, ohne eine zweite Abbuchung, Bestellung oder E-Mail auszulösen. GET, PUT und DELETE sind per Definition idempotent. POST ist es nicht.
Das übliche Bild ist der Aufzugknopf: Zehnmal gedrückt, kommt trotzdem ein Aufzug. Ein ungeschützter Knopf "Bezahlen" ist das Gegenteil, zehn Klicks können zehn Abbuchungen bedeuten. Idempotentes Design macht Wiederholungen sicher.
Idempotenz bei HTTP-Methoden
RFC 9110 (sie hat RFC 7231 abgelöst) legt fest, dass PUT, DELETE und alle sicheren Methoden idempotent sind:
| Methode | Idempotent? | Warum |
|---|---|---|
| GET, HEAD, OPTIONS, TRACE | Ja | Sichere Methoden: Sie lesen und ändern keinen Zustand |
| PUT | Ja | Ersetzt die Ressource jedes Mal durch dieselbe Darstellung |
| DELETE | Ja | Der erste Aufruf entfernt die Ressource, spätere finden nichts mehr zu entfernen |
| POST | Nein | Legt in der Regel bei jedem Aufruf eine neue Ressource an oder löst eine Aktion aus |
| PATCH | Nicht garantiert | Hängt vom Patch ab: Einen Wert setzen ist idempotent, hochzählen nicht |
Idempotent heißt nicht "liefert dieselbe Antwort". Ein erstes DELETE kann 204 liefern und eine Wiederholung 404, der Serverzustand ist trotzdem gleich. Die Eigenschaft beschreibt die beabsichtigte Wirkung auf den Server, nicht die Antwort. RFC 5789 hält fest, dass sich ein PATCH-Request so stellen lässt, dass er idempotent ist.
Beispiele
PUT /users/123mit{"name": "Alice"}setzt den Namen auf Alice. Zehn Aufrufe, dasselbe Ergebnis.DELETE /sessions/abchinterlässt keine Session abc, egal wie oft Sie es aufrufen.POST /orderslegt jedes Mal eine neue Bestellung an, zehn Aufrufe ergeben also zehn Bestellungen.PATCH /counters/xmit{"increment": 1}addiert jedes Mal eins. Das ist nicht idempotent.POST /emailsverschickt pro Aufruf eine Nachricht. Auch ein Nebeneffekt außerhalb Ihrer Datenbank zählt.
Warum Idempotenz wichtig ist
- Timeouts und Verbindungsabbrüche. Der Client kann nicht wissen, ob der Server die Anfrage vor dem Abbruch verarbeitet hat. Bei einer idempotenten Operation wiederholt er sie einfach.
- Automatische Wiederholungen. RFC 9110 erlaubt Clients, idempotente Anfragen nach einem Verbindungsfehler automatisch zu wiederholen, und verbietet Proxys, nicht idempotente Anfragen automatisch zu wiederholen. SDKs und Service Meshes folgen ähnlichen Regeln.
- At-least-once-Zustellung. Queues und Webhooks können dieselbe Nachricht mehrfach zustellen, der Empfänger muss Duplikate verkraften.
- Menschen. Nutzer klicken doppelt auf Absenden und laden halbfertige Seiten neu.
Idempotency-Keys
Für Operationen, die nicht von Natur aus idempotent sind, etwa eine Bestellung anlegen oder eine Karte belasten, ist der übliche Ansatz ein Idempotency-Key: ein eindeutiger Wert, den der Client für eine logische Operation erzeugt und bei jedem Versuch mitsendet.
POST /charges HTTP/1.1
Idempotency-Key: 8e0a4e6b-1b8e-4e3a-b9f7-5e1d3f9c4b8a
Content-Type: application/json
{"amount": 5000, "currency": "usd"}Der Server speichert das Ergebnis unter diesem Key. Eine Wiederholung mit demselben Key liefert das gespeicherte Ergebnis, statt die Operation erneut auszuführen. Stripe ist das bekannteste Beispiel und dokumentiert die Details: der Header Idempotency-Key, Keys mit bis zu 255 Zeichen, V4-UUIDs als Empfehlung, und bei API v1 werden Statuscode und Body der ersten Anfrage gespeichert und wiedergegeben, auch bei 500-Fehlern. Keys können nach mindestens 24 Stunden entfernt werden, und ein Key mit anderen Parametern führt zu einem Fehler. Für GET und DELETE braucht Stripe keine Keys, weil sie ohnehin idempotent sind.
Ein IETF-Draft (draft-ietf-httpapi-idempotency-key-header) arbeitet daran, den Header Idempotency-Key zu standardisieren. Er ist noch ein Internet-Draft und keine RFC. Er beschreibt eine 409-Antwort, wenn eine Wiederholung eintrifft, während die ursprüngliche Anfrage noch läuft, und eine 422, wenn ein Key mit anderem Payload erneut verwendet wird.
Keys auf dem Server umsetzen
- Den Key aus der Anfrage lesen und mit einem Fingerabdruck des Request-Bodys speichern.
- Den Key nachschlagen. Gibt es ein fertiges Ergebnis und stimmt der Fingerabdruck, wird es ohne Nebenwirkungen zurückgegeben.
- Weicht der Fingerabdruck ab, die Anfrage ablehnen (im Draft 422).
- Gibt es keinen Eintrag, den Key als in Bearbeitung vermerken, die Operation ausführen, die Antwort speichern und als erledigt markieren. Ein Unique-Constraint auf der Key-Spalte verhindert, dass zwei gleichzeitige Anfragen beide laufen.
- Ist der Key in Bearbeitung, warten oder 409 zurückgeben.
- Keys nach einem festen Zeitfenster ablaufen lassen, damit der Speicher nicht unbegrenzt wächst.
Häufige Fehler
- PATCH für idempotent halten.
{"set": 5}ist es,{"increment": 1}nicht. - Neuer Key pro Wiederholung. Der Key gehört zur Operation, nicht zum Versuch. Erzeugt jede Wiederholung einen frischen Key, wird nichts dedupliziert.
- Nebenwirkungen außerhalb der Datenbank vergessen. Ein "idempotenter" Endpunkt, der bei jedem Aufruf eine E-Mail sendet, ist nicht idempotent.
- Kein Ablauf. Jeden Key ewig zu behalten lässt den Speicher unbegrenzt wachsen. Wählen Sie ein Fenster, das die Wiederholungen Ihrer Clients abdeckt.
- Race Conditions. Zwei gleichzeitige Anfragen mit einem Key können beide laufen, wenn Sie nicht sperren oder einen Unique-Constraint nutzen.
- Sicher und idempotent verwechseln. Sicher heißt: keine Zustandsänderung (GET). PUT und DELETE sind idempotent, aber nicht sicher.
Idempotenz im Lasttest und Monitoring
- Nicht idempotente Endpunkte häufen Daten an. Ein POST-Test erzeugt in jeder Iteration Datensätze, planen Sie also eine Bereinigung ein oder nutzen Sie eine Testumgebung. Bei einem 5-Minuten-Intervall läuft eine Monitoring-Prüfung mit POST 288-mal am Tag, nehmen Sie daher lieber eine lesende Prüfung oder einen eigenen Test-Endpunkt.
- Pro virtuellem Nutzer und Iteration einen eindeutigen Key erzeugen. Verwenden alle virtuellen Nutzer denselben Key, erhalten sie alle die gespeicherte erste Antwort, und Ihr Test hat nur die erste Anfrage belastet.
- Den Mechanismus selbst testen. Senden Sie dieselbe Anfrage zweimal und auch gleichzeitig und prüfen Sie, dass die Antworten übereinstimmen und nur ein Datensatz existiert. Siehe API-Testing.
- Wiederholungen unter Last beobachten. Clients, die bei Timeouts wiederholen, erzeugen genau dann zusätzlichen Verkehr, wenn der Server langsam ist. So werden unter anderem Rate Limits erreicht (siehe Common Causes of API Rate Limiting, auf Englisch).
LoadFocus führt JMeter- und k6-Skripte aus 25 Cloud-Regionen aus (Lasttests), was sich für Tests mit gleichzeitigen Wiederholungen eignet. Wie jeder virtuelle Nutzer eigene Keys bekommt, steht in Data-Driven Load Testing Scripts, und für einen ersten API-Test in Load Testing RESTful APIs with LoadFocus (beide auf Englisch). Für geplante lesende Prüfungen gibt es API-Monitoring. Die CRUD-Verben hinter diesen Regeln erklärt CRUD-Operationen.
Häufige Fragen zur Idempotenz
Ist GET immer idempotent?
Per Definition ja: GET ist eine sichere Methode und sollte keinen Zustand ändern. Manche APIs missbrauchen GET für Aktionen wie Tracking oder Abmelden. Das bricht die Regel und lässt Prefetching und Wiederholungen die Aktion auslösen.
Ist PATCH idempotent?
Nicht per Definition. Es hängt von der Operation ab: Ein Feld auf einen Wert setzen ist idempotent, einen Zähler erhöhen nicht.
Was ist der Unterschied zwischen idempotent und sicher?
Sicher heißt: Die Anfrage soll den Serverzustand nicht ändern (GET, HEAD, OPTIONS). Idempotent heißt: Wiederholen hat dieselbe beabsichtigte Wirkung wie einmaliges Senden. PUT und DELETE sind idempotent, aber nicht sicher.
Wie mache ich einen POST-Request idempotent?
Senden Sie einen Idempotency-Key, einen eindeutigen Wert für die Operation, den Sie bei jeder Wiederholung beibehalten. Der Server speichert das erste Ergebnis unter diesem Key und liefert es bei Wiederholungen.
Wie lange sollte ein Idempotency-Key gelten?
Lange genug, um das Wiederholungsfenster Ihrer Clients abzudecken. Stripe entfernt Keys bei API v1 nach mindestens 24 Stunden. Wählen Sie Ihr eigenes Fenster und dokumentieren Sie es.
Gilt Idempotenz auch für GraphQL und gRPC?
Ja. GraphQL-Queries lesen Daten, Mutations brauchen eigenen Schutz, zum Beispiel einen Key im Input. gRPC erlaubt es, eine Methode in ihrer Definition als idempotent zu markieren, woran Clients erkennen, wann eine Wiederholung sicher ist.
Verwandte Begriffe
- Was ist JSON? Einsteiger-Guide mit Syntax und Beispielen
- Was ist JSON-RPC? Protokoll, Beispiele, REST-Vergleich
- Was ist multipart/form-data Content-Type? Datei-Uploads, Beispiele
- Was ist Swagger? Swagger und OpenAPI erklärt
- CRUD-Operationen: Create, Read, Update, Delete erklärt
- Was sind API-Angriffe?
- Was sind API-Cookies? Definition und Sicherheit
- API-Performance-Metriken: Latenz, Durchsatz, Fehlerrate
Verwandte LoadFocus-Tools
Setze dieses Konzept mit LoadFocus in die Praxis um, derselben Plattform, die alles antreibt, was du gerade gelesen hast.