Ist REST DELETE wirklich idempotent?

165

DELETE soll idempotent sein.

Wenn ich http://example.com/account/123 lösche, wird das Konto gelöscht.

Wenn ich es noch einmal mache, würde ich einen 404 erwarten, da das Konto nicht mehr existiert? Was ist, wenn ich versuche, ein Konto zu löschen, das noch nie existiert hat?

Ben Noland
quelle
11
Zusätzlich zu den Antworten würde ich vorschlagen, sich nicht zu sehr auf das idempotente Merkmal im Allgemeinen zu konzentrieren: Es sagt nichts über Kommutativität und gleichzeitige Anfragen aus. Zum Beispiel sollte N + 1 derselben "R1" -PUT-Anforderung den gleichen Effekt haben, aber Sie wissen nicht, ob ein anderer Client eine andere PUT / DELETE "R2" -Anforderung zwischen Ihnen gestellt hat, also während n R1 = R1 und m R2 = R2, etwas, bei dem Sie verschachtelte "R1" - und "R2" -Anfragen erhalten, sieht nicht unbedingt idempotent aus, wenn Sie nur die Perspektive eines einzelnen Clients einnehmen.
Bruno

Antworten:

187

Idempotenz bezieht sich auf den Status des Systems nach Abschluss der Anforderung


In allen Fällen (abgesehen von den Fehlerproblemen - siehe unten) existiert das Konto nicht mehr.

Von hier aus

"Methoden können auch die Eigenschaft" Idempotenz "haben, da ( abgesehen von Fehler- oder Ablaufproblemen ) die Nebenwirkungen von N> 0 identischen Anforderungen dieselben sind wie für eine einzelne Anforderung. Die Methoden GET, HEAD, PUT und DELETE teilen sich Diese Eigenschaft. Außerdem sollten die Methoden OPTIONS und TRACE KEINE Nebenwirkungen haben und sind daher von Natur aus idempotent. "


Das Schlüsselbit dort ist, dass die Nebenwirkungen von N> 0 identischen Anforderungen das gleiche sind wie für eine einzelne Anforderung.

Es ist richtig zu erwarten, dass der Statuscode anders ist, dies hat jedoch keinen Einfluss auf das Kernkonzept der Idempotenz. Sie können die Anforderung mehrmals senden, ohne den Status des Servers zu ändern.

Chris McCauley
quelle
3
Nebenwirkungen! == Serverstatus
wprl
2
@wprl Es gibt eine Debatte darüber, was dieser "Nebeneffekt" wirklich ist. Es kann sich um einen "Serverstatus" oder eine an den Client gesendete Antwort handeln. leedavis81.github.io/is-a-http-delete-requests-idempotent
Alireza
Hier ist ein Argument, dass 404 auf einem zweiten DELETE tatsächlich den Status des Servers ändern kann: stackoverflow.com/a/45194747/317522
Paulo Merson
1
@PauloMerson Danke, ich persönlich denke nicht, dass es wichtig ist, ob die zweite Rückgabe 404 oder 200 ist. Der Status des Servers hat sich nicht geändert, also bin ich damit zufrieden.
Chris McCauley
46

Bei Idempotent geht es um die Auswirkung der Anforderung, nicht um den Antwortcode, den Sie erhalten.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2 sagt:

Methoden können auch die Eigenschaft "Idempotenz" haben, da (abgesehen von Fehler- oder Ablaufproblemen) die Nebenwirkungen von N> 0 identischen Anforderungen dieselben sind wie für eine einzelne Anforderung.

Während Sie möglicherweise einen anderen Antwortcode erhalten, kann der Effekt des Sendens von N + 1 DELETE-Anforderungen an dieselbe Ressource als gleich angesehen werden.

Bruno
quelle
13

Der wichtige Unterschied besteht darin, dass sich idempotent auf Nebenwirkungen bezieht , nicht auf alle Effekte oder Reaktionen. Wenn Sie dies tun, DELETE http://example.com/account/123bewirkt dies, dass das Konto 123 jetzt vom Server gelöscht wird. Dies ist der einzige Effekt, die einzige Änderung des Serverstatus. Nehmen wir nun an, Sie führen dieselbe DELETE http://example.com/account/123Anforderung erneut aus. Der Server reagiert anders, aber sein Status ist der gleiche.

Es ist nicht so, dass die DELETE-Anforderung beschlossen hat, den Serverstatus auf eine andere Weise zu ändern, da das Konto fehlte, z. B. das Entfernen eines anderen Kontos oder das Hinterlassen eines Fehlerprotokolls. Nein, Sie können dieselbe DELETE-Anforderung millionenfach aufrufen und sicher sein, dass sich der Server in demselben Zustand befindet, in dem Sie ihn zum ersten Mal aufgerufen haben .

Janac Meena
quelle
7

Aus dem HTTP-RFC :

Methoden können auch die Eigenschaft "Idempotenz" haben, da (abgesehen von Fehler- oder Ablaufproblemen) die Nebenwirkungen von N> 0 identischen Anforderungen dieselben sind wie für eine einzelne Anforderung.

Beachten Sie, dass dies "Nebenwirkungen" und nicht "Reaktion" sind.

Fumanchu
quelle
7

Ja. Unabhängig vom Antwortcode.

Aus dem neuesten RFC für HTTP 1.1 (Schwerpunkt Mine):

Idempotente Methoden werden unterschieden, da die Anforderung automatisch wiederholt werden kann, wenn ein Kommunikationsfehler auftritt, bevor der Client die Antwort des Servers lesen kann. Wenn ein Client beispielsweise eine PUT-Anforderung sendet und die zugrunde liegende Verbindung geschlossen wird, bevor eine Antwort empfangen wird, kann der Client eine neue Verbindung herstellen und die idempotente Anforderung erneut versuchen. Es ist bekannt, dass das Wiederholen der Anforderung den gleichen beabsichtigten Effekt hat, selbst wenn die ursprüngliche Anforderung erfolgreich war, obwohl die Antwort möglicherweise unterschiedlich ist.

Es wird ausdrücklich darauf hingewiesen, dass die Antwort unterschiedlich sein kann. Noch wichtiger ist, dass der Grund des Konzepts aufgezeigt wird: Wenn eine Aktion idempotent ist, kann der Client die Aktion wiederholen, wenn ein Fehler auftritt, und weiß, dass dadurch nichts abstürzt. Wenn nicht, muss der Client (möglicherweise GET) eine zusätzliche Abfrage durchführen , um festzustellen, ob die vorherige wirksam ist, bevor er die Aktion sicher wiederholt. Solange der Server eine solche Garantie geben kann, ist die Aktion idempotent. Zitat aus einem anderen Kommentar :

Bei der Berechnung der Idempotenz geht es um die Robustheit eines Systems. Wie können Sie wiederherstellen, wenn ein Fehler erkannt wird, da ein Fehler auftreten kann (z. B. ein Netzwerkausfall)? Die einfachste Wiederherstellung besteht darin, es einfach noch einmal zu tun, aber das funktioniert nur, wenn es idempotent ist. ZB discard(x)ist idempotent, aber pop()nicht. Es geht nur um die Fehlerbehebung.

Franklin Yu
quelle
2

Ich denke das gleiche, 404 - Konto existiert nicht.

Sie könnten 400 - Bad Request argumentieren. Im Sinne von REST ist das Objekt, für das Sie eine Aktion ausgeführt haben, jedoch nicht vorhanden. Das entspricht 404.

Jason McCreary
quelle
1
Um eine 400 zu generieren, müsste man wissen, dass das Objekt früher existierte, was sehr unruhig ist.
Annakata
1
@annakata, 400 ist nicht einmal für Ressourcen gedacht, die früher vorhanden waren (vielleicht haben Sie 410 / Gone im Sinn), sondern für fehlerhafte Anfragen "Die Anfrage konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden."
Bruno
3
@Bruno - Ich bin mir bewusst, was es bedeutet, das OP hat es zitiert.
Annakata
1
Ich denke 200 wäre in Ordnung. Sie möchten, dass der Status des Servers lautet, dass das Konto nicht mehr vorhanden ist. Ist es wichtig, welche Anfrage es tatsächlich verschwinden ließ? Bei der zweiten Anforderung ist die Serveranforderung noch nicht geändert.
Andy
1

Zitiert aus meiner anderen Antwort hier :

In der Vergangenheit war RFC 2616, veröffentlicht 1999, die am häufigsten referenzierte HTTP 1.1-Spezifikation. Leider war die Beschreibung der Idempotenz vage , was Raum für all diese Debatten lässt. Diese Spezifikation wurde jedoch durch RFC 7231 ersetzt. Zitiert aus RFC 7231, Abschnitt 4.2.2 Idempotente Methoden , Hervorhebung von mir:

Eine Anforderungsmethode wird als "idempotent" betrachtet, wenn die beabsichtigte Auswirkung mehrerer identischer Anforderungen mit dieser Methode auf den Server mit der Auswirkung für eine einzelne solche Anforderung identisch ist. Von den durch diese Spezifikation definierten Anforderungsmethoden sind PUT-, DELETE- und sichere Anforderungsmethoden idempotent .

Es steht also in den Spezifikationen geschrieben, dass es bei der Idempotenz nur um die Auswirkungen auf den Server geht. Das erste LÖSCHEN, das ein 204 zurückgibt, und das nachfolgende LÖSCHEN, das 404 zurückgibt, macht ein derart unterschiedlicher Statuscode das LÖSCHEN NICHT nicht idempotent. Die Verwendung dieses Arguments zur Rechtfertigung einer nachfolgenden Rückgabe ist einfach irrelevant.


OK, es geht also nicht um Idempotenz. Aber dann könnte eine Folgefrage sein, was ist, wenn wir uns immer noch dafür entscheiden, 204 in nachfolgendem LÖSCHEN zu verwenden? Ist es o.k?

Gute Frage. Die Motivation ist verständlich: Dem Kunden zu ermöglichen, sein beabsichtigtes Ergebnis zu erreichen, ohne sich um die Fehlerbehandlung sorgen zu müssen. Ich würde sagen, 204 in nachfolgendem DELETE zurückzugeben, ist eine weitgehend harmlose serverseitige "Notlüge", die die clientseitige Seite nicht sofort erkennen wird. Deshalb gibt es Leute, die das in freier Wildbahn tun, und es funktioniert immer noch. Denken Sie daran, dass eine solche Lüge als semantisch seltsam angesehen werden kann, da "GET / non-exist" 404 zurückgibt, "DELETE / non-exist" jedoch 204 ergibt. Zu diesem Zeitpunkt würde der Kunde herausfinden, dass Ihr Service nicht vollständig den Anforderungen entspricht Abschnitt 6.5.4 404 Nicht gefunden .

Aber dann sollte der von RFC 7231 angedeutete beabsichtigte Weg, dh die Rückgabe von 404 bei nachfolgendem LÖSCHEN, überhaupt kein Problem sein. Viele weitere Entwickler haben sich dafür entschieden. Dies liegt vermutlich daran, dass jeder Client, der HTTP DELETE (oder eine andere HTTP-Methode) implementiert, nicht blind davon ausgehen würde, dass das Ergebnis immer 2xx erfolgreich ist. Sobald der Entwickler über die Fehlerbehandlung nachdenkt, ist 404 Not Found einer der ersten Fehler, die in den Sinn kommen. Zu diesem Zeitpunkt würde er / sie hoffentlich die Schlussfolgerung ziehen, dass es für eine HTTP-DELETE-Operation semantisch sicher ist, einen 404-Fehler zu ignorieren. Problem gelöst.

RayLuo
quelle