Ein Idempotency-Key lässt einen wiederholten Schreibvorgang genau einmal landen
Eine Verbindung kann abbrechen, nachdem der Schreibvorgang bereits stattgefunden hat, und von Ihrer Seite sieht das genauso aus wie eine Anfrage, die nie ankam. Senden Sie einen Idempotency-Key, und der Retry liefert die verpasste Antwort zurück, ohne eine zusätzliche Rechnung dahinter.
Was ist Idempotency
Idempotent heißt, dass zweimal tun Sie dort hinterlässt, wo einmal tun Sie hinterlassen hätte. Viele Anfragen arbeiten ohnehin so: eine Liste lesen oder ein Feld auf einen Wert setzen. Etwas anlegen nicht. Senden Sie dieselbe Rechnung zweimal, hält das System zwei Rechnungen. Jede API, die schreibt, muss also eine Frage beantworten. Wenn Sie nie erfahren haben, ob Ihre Anfrage durchkam, ist es dann sicher, sie erneut zu senden?
Ein Idempotency-Key ist die Antwort. Sie benennen den Vorgang, der Name reist mit der Anfrage, und alles, was unter einem schon beantworteten Namen ankommt, bekommt die ursprüngliche Antwort zurück, ohne zweite Ausführung dahinter. In der Buchhaltung ist dieser Unterschied schärfer als in den meisten Feldern, denn angelegt wird eine Buchung. Eine Dublette ist keine Zeile zum späteren Löschen, sie ist ein Eintrag, den jemand stornieren muss. Sie setzt auch die Grenze dessen, was Ihre Fehlerbehandlung leisten kann. Zu wissen, welche Fehler eine Wiederholung wert sind, ist der eine Teil des Problems, und Unified Error Handling deckt ihn ab. Danach zu handeln, ohne eine doppelte Buchung zu riskieren, ist der andere.
Eine abgebrochene Verbindung und eine doppelte Buchung
Derselbe Aufruf, zweimal ausgeführt. Einmal klappt er. Einmal läuft Ihre App in einen Timeout, bevor die Antwort ankommt, und da existiert die Rechnung im Zielsystem längst.
- Ihre AppmaesnPOST /bookingProposals
- maesnLexware Officeder Schreibvorgang, übersetzt
- Lexware Officemaesn201 Created
- maesnIhre App201 Created
Die Antwort trägt die Kennung des angelegten Objekts, sodass Ihre Seite sie festhalten und weitermachen kann.
- Ihre AppmaesnPOST /bookingProposals
- Ihre Appdie Verbindung bricht ab
- maesnLexware Officeder Schreibvorgang, übersetzt
- Lexware Officemaesn201 Created
- maesnIhre Appdie 201 hat kein Ziel mehr
Nachfragen ist der einzige Weg, es herauszufinden, und Nachfragen ist genau das, was die Dublette erzeugt.
Die zwei Spalten unterscheiden sich um ein Ereignis, und das kontrolliert niemand. Zwischen Ihrer Anfrage und ihrer Antwort sitzt ein Netz, und ein Netz bricht gelegentlich eine laufende Verbindung ab. Teuer wird das hier durch die Reihenfolge: Bis die Antwort verloren geht, hat das Zielsystem den Vorschlag längst gebucht. In der Zeichnung ist dieses System Lexware Office, und dieselbe Abfolge gilt, wo der Schreibvorgang auch landet. Ihre Seite hält einen Timeout und kein Ergebnis, und das ist der eine Zustand, in dem ein Schreibvorgang Sie nie zurücklassen sollte.
Ohne Key gibt es zwei Auswege, und beide kosten etwas. Sie können fragen, was geschah, und das heißt eine Supportanfrage und Warten. Oder Sie senden die Anfrage erneut, was ein richtiges Ergebnis liefert, wenn der Versuch scheiterte, und eine Dublette, wenn er gelang. Erneut zu senden tut Retry-Logik von sich aus, denn eine Wiederholung reagiert auf eine fehlende Antwort, und eine fehlende Antwort ist kein Beleg für einen fehlenden Schreibvorgang.
Drei Wege, auf denen dieselbe Rechnung zweimal rausgeht
Eine abgebrochene Verbindung ist der klarste Fall und nicht der häufigste. Zwei der drei sitzen über der API, wo der Sender nicht sieht, was schon rausgegangen ist.
Der Schreibvorgang läuft, aber die Antwort erreicht Sie nicht.
Die Retry-Logik reagiert auf eine fehlende Antwort, und die sagt nichts über den Aufruf.
Zwei Klicks, und die Warteschlange hinter dem Knopf erkennt nicht, dass es eine Rechnung ist.
Jeder muss von Hand im Zielsystem storniert werden, nachdem es jemandem auffällt.
Beim Klick lohnt das Verweilen, weil er am häufigsten in die Produktion gelangt und am seltensten eingeplant wird. Irgendwo in Ihrem Produkt gibt es einen Knopf, der eine Rechnung sendet, und einen Menschen, der erneut klickt, wenn sichtbar nichts passiert. Zwischen diesem Klick und dem Hauptbuch liegen vielleicht eine Warteschlange, ein Job-Runner und ein Konnektor, und keiner davon erkennt, dass die zwei Anfragen eine Rechnung beschreiben. Ein Idempotency-Key ist das Einzige in dieser Kette, das es kann, weil er der einzige Teil ist, den der Aufrufer benennen darf.
Der Header, der eine Wiederholung sicher macht
Der Key kommt mit Ihrer Anfrage an und entscheidet eines: ob dieser Vorgang schon beantwortet wurde. Alles andere am Aufruf bleibt, wie es war.
Nichts, was später zu finden und zu stornieren wäre.
Der Aufruf geht einmal durch, und seine Antwort wird 24 Stunden aufbewahrt.
Die aufbewahrte Antwort kommt zurück, und das Zielsystem wird nicht erneut gerufen.
Ein Header je Vorgang
Sie wählen einen Key, der den Vorgang identifiziert, und senden ihn mit dem Schreibvorgang. Jeder String geht, und eine fachliche Kennung liest sich im Log besser als eine UUID.
Die Wiederholung, die Sie schon fahren
Ihre heutige Retry-Logik wird allein durch den Header sicher, weil eine Wiederholung aus dem Gespeicherten antwortet statt einen neuen Schreibvorgang zu starten.
So abgegrenzt, dass Keys nicht kollidieren
Ein Key gehört zu einem Mandanten, einem Nutzer und einem Vorgang, sodass zwei Ihrer Kunden denselben Wert wählen können, ohne sich zu beeinflussen.
24 Stunden aufbewahrt
Die Antwort wird 24 Stunden nach Abschluss des Aufrufs gehalten, was eine Retry-Schleife, ein Ausfallfenster und eine Supportfrage am nächsten Morgen abdeckt.
POST /bookingProposalsx-api-key: YOUR_API_KEYx-account-key: CUSTOMER_ACCOUNT_KEYidempotency-key: order-12345-invoice-001Content-Type: multipart/form-datafile=@invoice.pdf
Die Abgrenzung macht einen selbst gewählten Key tragfähig. Ein Key wird nicht als globaler Wert gelesen, er gehört zu einem Mandanten, einem Nutzer und dem einen Vorgang, mit dem er gesendet wurde, zwei Ihrer Kunden können also am selben Morgen invoice-1 wählen und sich nie begegnen. Deshalb entwerfen Sie den Key und wir geben nie einen aus: Er muss nur innerhalb Ihrer eigenen Vorgänge eindeutig sein.
Geprüft wird nicht nur der Name, sondern auch die Anfrage selbst. Kommt derselbe Key mit anderen Daten dahinter an, ist das keine Wiederholung, sondern ein neuer Vorgang im alten Namen, und er wird mit einer 422 beantwortet. Auf der Kombination ruht die Zusage: Der Key sagt, welcher Vorgang das ist, und die Anfrage sagt, ob es noch derselbe ist.
Vier Antworten auf denselben Key
Eine Wiederholung nützt nur, wenn ihre Antwort eindeutig ist, der zweite Aufruf bekommt also keine allgemeine Bestätigung. Er bekommt eine von vier Antworten, und jede sagt Ihnen genau, was als nächstes zu tun ist. Drei davon sind ein Grund, sich keine Sorgen mehr zu machen, und eine ist ein Grund, den Key zu ändern statt den Zeitpunkt.
Gleicher Key, gleiche Anfrage, schon beantwortet
Sie bekommen den ursprünglichen Statuscode und Rumpf zurück, sodass Ihr Code denselben Zweig nimmt wie beim ersten Mal.
Gleicher Key, während der erste noch läuft
Der erste Versuch ist noch nicht fertig. Warten Sie kurz und fragen Sie erneut, statt einen zweiten zu öffnen.
Gleicher Key, aber der Anfragerumpf hat sich geändert
Dieser Key gehört schon zu einer anderen Nutzlast. Ein wirklich neuer Vorgang braucht einen neuen Key.
Die Idempotenzprüfung selbst kann nicht laufen
Es wurde nichts weitergegeben, also gibt es keine Dublette. Derselbe Key kann gefahrlos erneut gesendet werden.
Eine zurückgespielte Antwort ist die ursprüngliche, mit demselben Statuscode und demselben Rumpf, Ihr Code braucht dafür also keinen Zweig. Die 201, die Sie beim ersten Aufruf verarbeitet hätten, ist die 201, die Sie jetzt verarbeiten, und die Kennung darin zeigt auf den Datensatz, der schon existiert. Nichts in Ihrem Handler muss wissen, dass es auf einen zweiten Versuch blickt.
Beim asynchronen Schreiben gibt der Key die Task-ID zurück
Ein eingereihter Schreibvorgang antwortet sofort mit einer Task-ID und wird später fertig. Der Key hängt sich an diese erste Antwort, und das ändert, was eine Wiederholung bedeutet.
Das ist der Fall, in den ein ungeduldiger Aufrufer läuft, und es lohnt sich, ihn zu kennen, bevor Sie darum herum bauen. Ein eingereihter Schreibvorgang nach DATEV Unternehmen Online kann dauern, also sendet jemand, der auf einen Ladekreis schaut, die Anfrage erneut. Mit einem Key gibt diese Wiederholung dieselbe Task-ID zurück, statt einen weiteren Schreibvorgang einzureihen, und die Task-ID ist das, was Sie ohnehin abgefragt haben. Die Taktung hinter der Warteschlange gehört zu Asynchronous Processing, der Schreibvorgang bleibt also innerhalb der Limits jedes Systems, während Sie warten.
Ein Fehlschlag wird hier anders behandelt als ein Erfolg, und das mit Absicht. Scheitert der eingereihte Vorgang, wird der Key freigegeben, der naheliegende nächste Schritt funktioniert also: Daten korrigieren und unter demselben Key erneut senden, ohne einen neuen zu erfinden für etwas, das Sie weiterhin als einen Vorgang begreifen. Gelang er, bleibt der Key an diese Antwort gebunden, denn ihn wiederzuverwenden hieße, um die Dublette zu bitten, die er verhindern soll.
Was die Ebene trägt und was Ihr Code sendet
Idempotency ist ein kurzer Vertrag. Die eine Seite erkennt den Key und bewahrt die Antwort auf, die andere Seite sendet den Key.
- Erkennt den Key und den Vorgang, zu dem er gehört
- Bewahrt die erste Antwort 24 Stunden auf
- Spielt sie mit demselben Statuscode und Rumpf zurück
- Antwortet 409, solange der erste Aufruf noch läuft
- Antwortet 422, wenn der Key für andere Daten wiederkommt
- Wählt einen Key, der den Vorgang identifiziert
- Sendet ihn bei der Wiederholung mit, die Sie ohnehin fahren
- Nutzt einen neuen Key für einen wirklich neuen Vorgang
Das untere Band ist der gesamte Anbindungsaufwand, und darum stehen die beiden untereinander. Es gibt keinen Zustand zu halten, keine Tabelle gesendeter Schreibvorgänge je Kunde und keinen Abgleichlauf, der die Paare hinterher sucht. Der Key, den Sie in Ihrem eigenen Datenmodell schon haben, eine Auftragsnummer oder eine Rechnungsreferenz, ist meist der Key, den der Header will, und deshalb empfiehlt die Doku eine fachliche Kennung vor einer erzeugten. Jede Anfrage und jede Antwort darum herum wird aufgezeichnet, sechs Wochen später schlagen Sie den Vorgang also über Protokollierung und Monitoring nach und sehen genau, welcher es war.
Ein Header statt eines Abgleichlaufs
- Jeden Schreibvorgang speichern, je Kunde
- Herausfinden, ob ein Fehler ankam
- Abgleichen, um Dubletten zu finden
- Eine Buchung im Hauptbuch stornieren
- Einen Header mitsenden
- Die Wiederholung gibt die erste Antwort
- Ein Systemaufruf je Schreibvorgang
- Nichts, was danach abzugleichen wäre
Eine doppelte Buchung ist auf eine Weise teuer, die schlecht skaliert. Sie fällt spät auf, meist dem Buchhalter des Kunden und nicht Ihrem Monitoring, sie muss im Zielsystem von Hand storniert werden, und das Gespräch darüber landet bei dem, der am nächsten steht. Volumen macht es schlimmer: Eine Reisemanagement-Plattform, die Lieferantenrechnungen für Hunderte Gesellschaften nach DATEV schiebt, und genau das tut Lanes & Planes, kann unmöglich jeden Schreibvorgang von Hand prüfen.
Den Vorgang zu benennen verschiebt diese ganze Problemklasse in den Moment, in dem die Anfrage gestellt wird, und das ist der einzige Moment, in dem jemand genug Kontext hat, um damit umzugehen. Die Wiederholung wird zu etwas Sicherem, und die Arbeit, die sie spart, ist die Art, die Produkt- und Entwicklungsteams sonst jahrelang pflegen würden, eine Zustandstabelle und einen Abgleichlauf nach dem anderen.
Häufige Fragen
Was ist ein Idempotency-Key?
Kann ich Idempotency auf den Endpunkten nutzen, auf die meine Anbindung schreibt?
Wie lange ist ein Idempotency-Key gültig?
Wie erzeuge ich Idempotency-Keys?
Was passiert, wenn ich einen Key mit anderem Anfragerumpf wiederverwende?
Was passiert, wenn ich wiederhole, während die erste Anfrage noch läuft?
Funktioniert Idempotency auf asynchronen Endpunkten?
Kann ich einen Key nach einer gescheiterten Anfrage wiederverwenden?
Was, wenn die Idempotenzprüfung selbst nicht verfügbar ist?
Brauche ich trotzdem eine eigene Retry-Logik?
Ist ein Idempotency-Key Pflicht?
Einmal bauen, auf der Unified API.
Sehen Sie, wie Idempotency für Ihre Integration funktioniert, oder steigen Sie in die technische Referenz ein.











