Sollte eine RESTful 'PUT'-Operation etwas zurückgeben

437

Ich habe mich gefragt, was die Leute von einer RESTful- PUTOperation halten, die nichts (null) im Antworttext zurückgibt.

AwkwardCoder
quelle

Antworten:

613

Die HTTP-Spezifikation ( RFC 2616 ) enthält eine Reihe von Empfehlungen, die anwendbar sind. Hier ist meine Interpretation:

  • HTTP-Statuscode 200 OKfür eine erfolgreiche PUT eines Updates einer vorhandenen Ressource. Kein Antwortkörper erforderlich. (Pro Abschnitt 9.6 , 204 No Contentist noch besser geeignet.)
  • HTTP-Statuscode 201 Createdfür eine erfolgreiche PUT einer neuen Ressource, wobei der spezifischste URI für die neue Ressource im Feld Standortheader zurückgegeben wird und alle anderen relevanten URIs und Metadaten der Ressource im Antworttext wiedergegeben werden. ( RFC 2616 Abschnitt 10.2.2 )
  • HTTP - Statuscode 409 Conflictfür einen PUT , die aufgrund einer 3 nicht erfolgreich ist rd -Party Modifikation, mit einer Liste der Unterschiede zwischen der versuchten Aktualisierung und der aktuellen Ressource im Antworttext. ( RFC 2616 Abschnitt 10.4.10 )
  • HTTP-Statuscode 400 Bad Requestfür eine nicht erfolgreiche PUT mit Text in natürlicher Sprache (z. B. Englisch) im Antworttext, der erklärt, warum die PUT fehlgeschlagen ist. ( RFC 2616 Abschnitt 10.4 )
System PAUSE
quelle
25
@stian Interessant! Das erscheint Mozilla ziemlich anmaßend, da ich in RFC 2616 nichts finden kann (insbesondere Abschnitte 10.2 Erfolgreich 2xx und 10.2.1 200 OK ) die Verwendung von 200PUT, DELETE oder einer anderen Methode ausdrücklich ausschließt . Habe ich etwas verpasst? Wie Mozilla wird der Chef von W3 und der IETF? ;) Oder vielleicht haben sie noch nie von Postels Robustheitsprinzip gehört.
System PAUSE
52
@stian: Dieser Satz wurde am 3. Februar 2013 entfernt. Wahrscheinlich, weil hier jemand darüber gelesen hat. ;) developer.mozilla.org/en-US/docs/HTTP/…
Christian Strempfer
6
Die Semantik der PUT-Methode besteht darin, den aktuellen Status der Ressource zu ignorieren. Daher ist es nur dann sinnvoll, einen 409-Konflikt für einen PUT zurückzugeben, der aufgrund einer Änderung durch einen Drittanbieter nicht erfolgreich ist, wenn die Anforderung bedingt ist.
Pedro Werneck
8
@systemPAUSE Schöne Antwort. Ein kleiner Punkt: Wenn Sie einen Antwortkörper nicht auf eine erfolgreiche Operation zurückführen möchten, würde ich empfehlen, ausschließlich einen 204 zu verwenden. Einige Clients (z. B. jQuery Ajax) ersticken, wenn sie eine Antwort ungleich Null erwarten, diese aber nicht erhalten. Sie können ein Beispiel dafür in dieser Frage sehen .
nick_w
3
Möglicherweise wurde RFC2616 aktualisiert, seit dies beantwortet wurde. Nein, wo in 9.6 No response body neededin Bezug auf eine 200 erwähnt wird. Tatsächlich wird der Antwortkörper in Bezug auf eine PUT überhaupt nicht erwähnt. Es heißt nurIf an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.
James
163

Im Gegensatz zu den meisten Antworten hier denke ich tatsächlich, dass PUT die aktualisierte Ressource zurückgeben sollte (natürlich zusätzlich zum HTTP-Code).

Der Grund, warum Sie die Ressource als Antwort auf den PUT-Vorgang zurückgeben möchten, liegt darin, dass der Server beim Senden einer Ressourcendarstellung an den Server auch eine Verarbeitung auf diese Ressource anwenden kann, sodass der Client wissen möchte, wie diese Ressource funktioniert Es sieht so aus, als ob die Anfrage erfolgreich abgeschlossen wurde. (Andernfalls muss eine weitere GET-Anforderung ausgegeben werden.)

LiorH
quelle
3
"Der Server kann auch eine Verarbeitung auf diese Ressource anwenden": Ich bin dies neu. Ist das wirklich RESTful?
Raedwald
22
@ Raedwald sicher ist es. Für REST muss nicht die gesamte Ressource auf einem PUT aktualisiert werden, obwohl dies allgemein empfohlen wird. Einige Felder sind möglicherweise für die Aktualisierung nicht sinnvoll. Das Erstellungsdatum oder das Datum der letzten Änderung sollten beispielsweise wahrscheinlich nicht im PUT-Text enthalten sein, werden jedoch wahrscheinlich aufgrund des PUT geändert. Trotzdem stimme ich LiorH nicht zu, dass ein PUT zu einer Rückgabe der Ressource führen sollte. Ich würde ein GET nach dem PUT benötigen, um die aktualisierte Ressource zu erhalten.
Randolpho
19
@Randolpho REST erfordert nicht, dass die gesamte Ressource auf einem PUT aktualisiert wird. Sollte dies nicht bei einem PATCH der Fall sein?
Marco Ciambrone
14
@MarcoCiambrone Ja, ich stimme zu und widerrufe meinen vorherigen Kommentar. Ich habe meine Einstellung für REST und PUT geändert - PUT sollte immer idempotent sein und niemals für ein teilweises Update verwendet werden. POST ist die einzige Alternative, sofern PATCH nicht unterstützt wird. In diesem Fall kann PATCH eine gute Alternative sein. PATCH ist jedoch ein neues Verb und wird möglicherweise von einigen serverseitigen Frameworks nicht unterstützt.
Randolpho
2
Die Antwort wurde lange vor rfc7231 geschrieben, aber Abschnitt 4.3.4 macht deutlich: "Die PUT-Methode fordert an, dass der Status der Zielressource erstellt oder durch den Status ersetzt wird, der durch die in der Nutzlast der Anforderungsnachricht enthaltene Darstellung definiert ist"
aaaaaa
3

Ich denke, es ist für den Server möglich, Inhalte als Antwort auf einen PUT zurückzugeben. Wenn Sie ein Antwortumschlagformat verwenden, das seitlich geladene Daten zulässt (z. B. das von Glutdaten verwendete Format), können Sie auch andere Objekte einschließen, die möglicherweise über Datenbankauslöser usw. geändert wurden (seitlich geladene Daten werden explizit reduziert Anzahl der Anfragen, und dies scheint ein guter Ort zur Optimierung zu sein.)

Wenn ich nur den PUT akzeptiere und nichts zu melden habe, verwende ich den Statuscode 204 ohne Text. Wenn ich etwas zu melden habe, verwende ich den Statuscode 200 und füge einen Text hinzu.

shaunc
quelle
2

Die HTTP / 1.1-Spezifikation (Abschnitt 9.6) werden die entsprechenden Antwort- / Fehlercodes erläutert. Der Antwortinhalt wird jedoch nicht behandelt.

Was würden Sie erwarten? Ein einfacher HTTP-Antwortcode (200 usw.) erscheint mir unkompliziert und eindeutig.

Brian Agnew
quelle
Ja, aber was ist, wenn Sie überprüfen möchten, ob die nach einem PUT oder POST in db eingefügten Daten wirklich die gewünschten Daten darstellen. Es wäre besser, wenn das HTTP den Hauptteil der Antwort zurücksenden könnte.
tnkh
1
@tnkh was Sie vorschlagen, ist geradezu eine schreckliche Idee. Führen Sie nach einem erfolgreichen Update einen separaten GET-Aufruf durch, um das gewünschte Ergebnis zu erzielen. Um die Leistung sicherzustellen, führen Sie eine Caching-Ebene ein, wenn Sie Probleme in dieser Abteilung haben. Wir können diese Probleme nicht lösen, indem wir mit der Logik „Alles geht“ herumspielen. Spielen Sie nicht mit 'soliden' und grundlegenden Programmierprinzipien herum, die im Jahr 2020 vernünftig sein sollten. Es ist eine Schande!
XDS
@XDS Ich bestätige Ihren ersten Teil des Kommentars. Aber ich kann nicht aufhören, meine Augen danach zu verdrehen. Urkomischer Kommentar
tnkh
Vielen Dank, dass Sie näher erläutert haben, warum Sie es lustig finden.
XDS
2

Wenn das Backend der REST-API eine relationale SQL-Datenbank ist, dann

  1. Sie sollten RowVersion in jedem Datensatz haben, der aktualisiert werden kann (um das Problem der verlorenen Aktualisierung zu vermeiden ).
  2. Sie sollten nach dem PUT immer eine neue Kopie des Datensatzes zurückgeben (um die neue RowVersion zu erhalten ).

Wenn Sie sich nicht für verlorene Updates interessieren oder Ihre Clients dazu zwingen möchten, unmittelbar nach einem PUT ein GET durchzuführen, geben Sie nichts vom PUT zurück.

John Henckel
quelle
1

HTTP-Antwortcode 201 für "Erstellt" zusammen mit einem "Standort" -Header, der angibt, wo der Client die neu erstellte Ressource finden kann.

dc360
quelle
5
PUT-Objekte sind (oder sollten nicht) neu erstellte Ressourcen
kdazzle
9
@kdazzle PUT kann sicherlich eine neu erstellte Ressource sein und würde es oft sein. w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Charlie Schliesser
3
Nur um meinen Kommentar etwas besser zu erklären. PUT bedeutet, dass Sie diesen Artikel an dieser bestimmten Stelle platzieren und die derzeit vorhandenen Elemente ersetzen (falls zutreffend).
user1751825
3
Richtig, "ersetzen, was gerade da ist" ist der Schlüsselbegriff. Es sollte bereits existieren und wird ersetzt. PUT sollte nicht zum Erstellen neuer Ressourcen dienen.
Kevin M
3
@ KevinM Wie im neuesten RFC-Dokument rfc7231 heißt es, dass Ressourcen erstellt werden können: "Die PUT-Methode fordert an, dass der Status der Zielressource erstellt oder ersetzt wird [...]" und der Grund, aus dem Sie glauben , dass PUT nicht erstellt werden kann Neue Ressource ist, weil Sie den Speicherort der neuen Ressource nicht unbedingt kennen. Wenn Sie jedoch den Standort / die Kennung kennen, kann diese erstellt werden, wenn sie noch nicht vorhanden ist.
Leo Lei
0

Ich habe die RESTful-API in meinen Diensten verwendet, und hier ist meine Meinung: Zuerst müssen wir zu einer gemeinsamen Ansicht gelangen: PUTWird verwendet, um eine Ressource zu aktualisieren, die nicht erstellt oder abgerufen wurde.

Ich habe Ressourcen definiert mit: Stateless resourceund Stateful resource:

  • Statuslose Ressourcen Für diese Ressourcen ist es ausreichend, den HttpCode mit leerem Text zurückzugeben.

  • Stateful Resources Zum Beispiel: die Version der Ressource. Für diese Art von Ressourcen müssen Sie die Version angeben, wenn Sie sie ändern möchten. Geben Sie daher die vollständige Ressource zurück oder geben Sie die Version an den Client zurück, damit der Client nach der Aktualisierungsaktion keine Abrufanforderung senden muss.

Aber , für einen Dienst oderSystem, haltenessimple,clearly,easy to use and maintainist das Wichtigste.

Bruce
quelle
6
"PUT wird verwendet, um eine Ressource zu aktualisieren, die nicht erstellt oder abgerufen wurde." - das ist weder wahr noch üblich. Nach Spezifikation kann PUT die Ressource erstellen. Clear = gemäß der allgemein bekannten Spezifikation.
Imre Pühvel
-3

So wie ein leerer Anfragetext dem ursprünglichen Zweck einer GET-Anforderung entspricht und ein leerer Antworttext dem ursprünglichen Zweck einer PUT-Anforderung entspricht.

AnthonyWJones
quelle
-3

scheint in Ordnung zu sein ... obwohl ich denke, ein rudimentärer Hinweis auf Erfolg / Misserfolg / Zeitangabe / # empfangene Bytes / etc. wäre vorzuziehen.

Bearbeiten: Ich habe im Sinne von Datenintegrität und / oder Aufzeichnungen gedacht. Metadaten wie ein MD5-Hash oder ein Zeitstempel für die empfangene Zeit können für große Datendateien hilfreich sein.

Jason S.
quelle
1
Wie wäre es mit 200 OK im Statusantwort-Header? Denken Sie, das ist genug, um zu sagen: "Hat gut funktioniert, danke?"
AnthonyWJones
Der Antwortheader würde den Statuscode enthalten, und ja, wir sprechen an dieser Stelle über HTTP :)
AwkwardCoder
-4

Im Idealfall wird eine Erfolgs- / Fehlerantwort zurückgegeben.

cgp
quelle
13
Nicht im Antwortkörper. Der HTTP-Statuscode ist der Ort dafür. Vielleicht, wenn es einen Fehler gibt, könnten einige erweiterte Fehlerinformationen in der Antwort bidy zurückgegeben werden
The Archetypal Paul
-4

Es gibt einen Unterschied zwischen dem Header und dem Text einer HTTP-Antwort. PUT sollte niemals einen Body zurückgeben, sondern muss einen Antwortcode im Header zurückgeben. Wählen Sie einfach 200, wenn es erfolgreich war, und 4xx, wenn nicht. Es gibt keinen Null-Rückkehrcode. Warum willst du das tun?

AlexanderJohannesen
quelle