6336 Stimmen

Was ist der Unterschied zwischen POST und PUT in HTTP?

Hintergrundinformationenanalyse:

Gemäß RFC 2616, § 9.5 wird POST verwendet, um eine Ressource zu erstellen:

Die POST-Methode wird verwendet, um zu fordern, dass der Ursprungsserver die im Request eingebettete Entität als neue untergeordnete Ressource der im Request-Zeilen-URI identifizierten Ressource akzeptiert.

Gemäß RFC 2616, § 9.6 wird PUT verwendet, um eine Ressource zu erstellen oder zu ersetzen:

Die PUT-Methode fordert, dass die eingebettete Entität unter dem bereitgestellten Request-URI gespeichert wird. Wenn der Request-URI auf eine bereits vorhandene Ressource verweist, sollte die eingebettete Entität als modifizierte Version derjenigen angesehen werden, die auf dem Ursprungsserver liegt. Wenn der Request-URI nicht auf eine vorhandene Ressource zeigt und dieser URI als neue Ressource vom anfordernden User-Agent definiert werden kann, kann der Ursprungsserver die Ressource mit diesem URI erstellen.

Meine Frage:

Also, welche HTTP-Methode sollte verwendet werden, um eine Ressource zu erstellen? Oder sollten beide unterstützt werden?

66 Stimmen

Es kann hilfreich sein, die Definitionen in HTTPbis zu verwenden - Roy hat sich viel Arbeit gemacht, um sie zu klären. Siehe: tools.ietf.org/html/…

19 Stimmen

Nur um den Kommentar von @MarkNottingham auf den neuesten Stand zu bringen, hier sind POST und PUT, wie sie auf HTTPbis definiert sind.

48 Stimmen

Es scheint mir, dass dieser Diskurs aus der gängigen Praxis entstanden ist, REST durch die Beschreibung der HTTP-Methoden in Bezug auf CRUD-Operationen zu vereinfachen.

4884voto

Brian R. Bondy Punkte 325712

Insgesamt:

Sowohl PUT als auch POST können für die Erstellung verwendet werden.

Sie müssen sich fragen, "auf welches Objekt bezieht sich die Aktion?", um zu unterscheiden, welche Methode Sie verwenden sollten. Nehmen wir an, Sie entwerfen eine API, um Fragen zu stellen. Wenn Sie POST verwenden möchten, würden Sie das für eine Liste von Fragen tun. Wenn Sie PUT verwenden möchten, würden Sie das für eine bestimmte Frage tun.

Beide können verwendet werden, also welche sollte ich in meinem RESTful Design verwenden:

Sie müssen nicht PUT und POST unterstützen.

Welche Methode Sie verwenden, liegt bei Ihnen. Denken Sie jedoch daran, die richtige Methode je nach dem Objekt zu verwenden, auf das Sie in der Anfrage verweisen.

Einige Überlegungen:

  • Nennen Sie die URL-Objekte, die Sie erstellen, explizit oder lassen Sie den Server entscheiden? Wenn Sie sie benennen, verwenden Sie PUT. Wenn Sie den Server entscheiden lassen, verwenden Sie POST.
  • PUT wird angenommen, idempotent zu sein, also wenn Sie ein Objekt zweimal PUTten, sollte dies keine zusätzliche Auswirkung haben. Dies ist eine schöne Eigenschaft, also würde ich PUT verwenden, wenn möglich. Stellen Sie einfach sicher, dass die PUT-Idempotenz tatsächlich korrekt auf dem Server implementiert ist.
  • Sie können eine Ressource mit PUT unter derselben Objekt-URL aktualisieren oder erstellen.
  • Mit POST können zwei Anfragen gleichzeitig eintreffen, die Änderungen an einer URL vornehmen, und sie können verschiedene Teile des Objekts aktualisieren.

Ein Beispiel:

Ich habe folgendes als Teil einer weiteren Antwort auf SO zu diesem Thema geschreiben:

POST:

Wird verwendet, um eine Ressource zu ändern und zu aktualisieren

POST /questions/ HTTP/1.1
Host: www.example.com/

Beachten Sie, dass das Folgende ein Fehler ist:

POST /questions/ HTTP/1.1
Host: www.example.com/

Wenn die URL noch nicht erstellt wurde, sollten Sie nicht POST verwenden, um sie zu erstellen, während Sie den Namen angeben. Dies sollte zu einem 'Ressource nicht gefunden' Fehler führen, weil noch nicht existiert. Sie sollten zuerst die -Ressource mit PUT auf dem Server platzieren.

Sie könnten jedoch etwas wie dies tun, um Ressourcen mit POST zu erstellen:

POST /questions HTTP/1.1
Host: www.example.com/

Beachten Sie, dass in diesem Fall der Name der Ressource nicht angegeben ist, der Pfad der neuen Objekte URL würde an Sie zurückgegeben.

PUT:

Wird verwendet, um eine Ressource zu erstellen oder zu überschreiben. Während Sie die neue URL der Ressourcen angeben.

Für eine neue Ressource:

PUT /questions/ HTTP/1.1
Host: www.example.com/

Zum Überschreiben einer vorhandenen Ressource:

PUT /questions/ HTTP/1.1
Host: www.example.com/

Zusätzlich und etwas prägnanter, RFC 7231 Abschnitt 4.3.4 PUT besagt (Hervorhebung hinzugefügt),

4.3.4. PUT

Die PUT-Methode fordert, dass der Zustand der Zielressource mit dem Zustand, der durch die im Anfrage-Nachrichtspayload enthaltene Repräsentation definiert ist, erstellt oder ersetzt wird.

1221 Stimmen

Ich denke, man kann nicht genug betonen, dass PUT idempotent ist: Wenn das Netzwerk gestört ist und der Client sich nicht sicher ist, ob seine Anfrage durchgekommen ist, kann er sie einfach ein zweites (oder hundertstes) Mal senden, und es ist durch die HTTP-Spezifikation garantiert, dass dies genau den gleichen Effekt hat wie das einmalige Senden.

91 Stimmen

@Jörg W Mittag: Nicht notwendig. Das zweite Mal könnte einen 409 Conflict oder ähnliches zurückgeben, wenn die Anfrage in der Zwischenzeit geändert wurde (von einem anderen Benutzer oder der ersten Anfrage selbst, die durchgekommen ist).

2 Stimmen

Ich denke, es gibt keinen Unterschied in der Definition. 409 Konflikt könnte sogar das Ergebnis der ersten Anfrage sein, die der Client gestellt hat. In jedem Fall sollte es das Problem untersuchen.

2576voto

Cheeso Punkte 184210

Sie können im Web Behauptungen finden, die besagen

Keine davon ist ganz richtig.


Besser ist es, zwischen PUT und POST basierend auf Idempotenz der Aktion zu wählen.

PUT impliziert das Einsetzen einer Ressource - das vollständige Ersetzen dessen, was unter der angegebenen URL verfügbar ist, durch etwas anderes. Per Definition ist ein PUT idempotent. Machen Sie es so oft Sie wollen, und das Ergebnis ist dasselbe. x=5 ist idempotent. Sie können eine Ressource PUTen, egal ob sie zuvor existierte oder nicht (z. B., um zu erstellen oder zu aktualisieren)!

POST aktualisiert eine Ressource, fügt eine Nebenressource hinzu oder verursacht eine Änderung. Ein POST ist nicht idempotent, so wie x++ nicht idempotent ist.


Nach diesem Argument wird PUT zum Erstellen verwendet, wenn Sie die URL der Sache kennen, die Sie erstellen werden. POST kann zum Erstellen verwendet werden, wenn Sie die URL der "Fabrik" oder des Managers für die Kategorie von Dingen kennen, die Sie erstellen möchten.

Also:

POST /expense-report

oder:

PUT  /expense-report/10929

86 Stimmen

Ich stimme zu, wo immer Idempotenz betroffen ist, sollte es alle anderen Anliegen überwiegen, da dies viele unerwartete Fehler verursachen kann, wenn es falsch ist.

2 Stimmen

Ja. Tatsächlich widersetzt sich das AtomPub-Protokoll diesem (oder genauer gesagt, beschränkt seine semantische Bedeutung von PUT): "PUT wird verwendet, um eine bekannte Ressource zu bearbeiten. Es wird nicht für die Erstellung von Ressourcen verwendet." Nur weil das AtomPub-Protokoll das sagt (was übrigens gültig ist), bedeutet das nicht, dass alle RESTful-Protokolle es befolgen müssen. (weil REST generisch ist)

20 Stimmen

Wenn POST eine Ressource aktualisieren kann, wie kann das dann nicht idempotent sein? Wenn ich das Alter eines Schülers mit PUT ändere und das 10 Mal mache, bleibt das Alter des Schülers dasselbe, als wenn ich es nur einmal gemacht hätte.

849voto

Nigel Thorne Punkte 20178
  • POST an eine URL erstellt ein untergeordnetes Ressourcen an einer serverdefinierten URL.
  • PUT an eine URL erstellt/ersetzt die Ressource als Ganzes an der vom Client definierten URL.
  • PATCH an eine URL aktualisiert Teile der Ressource an dieser vom Client definierten URL.

Die relevante Spezifikation für PUT und POST ist RFC 2616 §9.5ff.

POST erstellt eine untergeordnete Ressource, also erstellt POST zu /items eine Ressource, die unter der /items Ressource liegt. Zum Beispiel. /items/1. Das Senden des gleichen POST-Pakets zweimal erstellt zwei Ressourcen.

PUT dient dazu, eine Ressource an einer vom Client bekannten URL zu erstellen oder zu ersetzen.

Also: PUT ist nur eine Option für CREATE, wenn der Client die URL bereits kennt, bevor die Ressource erstellt wird. z.B. /blogs/nigel/entry/when_to_use_post_vs_put da der Titel als Schlüssel für die Ressource verwendet wird

PUT ersetzt die Ressource an der bekannten URL, wenn sie bereits existiert, daher hat das zweimalige Senden derselben Anfrage keine Auswirkungen. Mit anderen Worten, Aufrufe an PUT sind idempotent.

Der RFC liest sich wie folgt:

Der grundlegende Unterschied zwischen den POST- und PUT-Anfragen spiegelt sich in der unterschiedlichen Bedeutung des Request-URI wider. Die URI in einer POST-Anfrage identifiziert die Ressource, die die beigefügte Entität verarbeiten wird. Diese Ressource kann ein Datenakzeptierungsprozess, ein Gateway zu einem anderen Protokoll oder eine separate Entität sein, die Anmerkungen akzeptiert. Im Gegensatz dazu identifiziert die URI in einer PUT-Anfrage die Entität, die mit der Anfrage beigefügt wird - der Benutzeragent weiß, für welchen URI er gedacht ist, und der Server DARF NICHT versuchen, die Anfrage auf eine andere Ressource anzuwenden. Wenn der Server möchte, dass die Anfrage auf einen anderen URI angewendet wird,

Hinweis: PUT wurde hauptsächlich zum Aktualisieren von Ressourcen (durch vollständiges Ersetzen) verwendet, aber in letzter Zeit gibt es eine Bewegung hin zur Verwendung von PATCH zur Aktualisierung vorhandener Ressourcen, da PUT angibt, dass es die gesamte Ressource ersetzt. RFC 5789.

Update 2018: Es gibt einen Fall, der dazu führen kann, PUT zu vermeiden. Siehe "REST ohne PUT"

Mit der Technik "REST ohne PUT" sollen Verbraucher gezwungen werden, neue 'nomenalisierte' Anforderungsressourcen zu posten. Wie bereits diskutiert, ist das Ändern der Postadresse eines Kunden ein POST zu einer neuen "ChangeOfAddress"-Ressource, nicht ein PUT einer "Customer"-Ressource mit einem anderen Postadressfeldwert.

entnommen aus REST API Design - Ressourcenmodellierung von Prakash Subramaniam von Thoughtworks

Dadurch wird die API dazu gezwungen, Zustandsübergangsprobleme mit mehreren Clients, die eine einzelne Ressource aktualisieren, zu vermeiden, und passt besser zu Ereignisquellen und CQRS. Wenn die Arbeit asynchron erledigt wird, scheint das Posten der Transformation und das Warten darauf, dass sie angewendet wird, angemessen.

70 Stimmen

Oder von der anderen Seite des Zauns: PUT, wenn der Client die Adresse des resultierenden Ressourcen bestimmt, POST, wenn der Server es tut.

4 Stimmen

Ich denke, dass diese Antwort bearbeitet werden sollte, um deutlicher zu machen, was @DanMan auf sehr einfache Weise angemerkt hat. Was ich hier am wertvollsten finde, ist die Anmerkung am Ende, dass ein PUT nur zum Ersetzen der gesamten Ressource verwendet werden sollte.

4 Stimmen

PATCH ist für mindestens ein paar Jahre keine realistische Option, aber ich stimme der Ideologie zu.

332voto

Alexander Torstling Punkte 17776

POST bedeutet "Neu erstellen", wie in "Hier ist die Eingabe zum Erstellen eines Benutzers, erstelle sie für mich".

PUT bedeutet "Einfügen, ersetzen, wenn bereits vorhanden", wie in "Hier sind die Daten für Benutzer 5".

Sie POST zu example.com/users, da Sie die URL des Benutzers noch nicht kennen und den Server bitten möchten, diese zu erstellen.

Sie PUT zu example.com/users/id, da Sie einen spezifischen Benutzer ersetzen/erstellen möchten.

Zweimal mit den gleichen Daten zu posten bedeutet, dass zwei identische Benutzer mit unterschiedlichen IDs erstellt werden. Das zweimalige Durchführen eines PUTs mit den gleichen Daten erstellt den Benutzer beim ersten Mal und aktualisiert ihn beim zweiten Mal auf denselben Zustand (keine Änderungen). Da Sie nach einem PUT immer denselben Zustand erreichen, unabhängig davon, wie oft Sie ihn ausführen, wird er als "gleich potent" bezeichnet - idempotent. Dies ist nützlich für das automatische Wiederholen von Anfragen. Keine weiteren "Sind Sie sicher, dass Sie die Anfrage erneut senden möchten", wenn Sie die Zurücktaste im Browser drücken.

Ein allgemeiner Ratschlag ist, POST zu verwenden, wenn Sie möchten, dass der Server die URL-Generierung Ihrer Ressourcen steuert. Verwenden Sie andernfalls PUT. Bevorzugen Sie PUT gegenüber POST.

30 Stimmen

Unordentlichkeit kann dazu geführt haben, dass allgemein angenommen wird, dass es nur zwei Verben gibt, die du brauchst: GET und POST. GET, um zu erhalten, POST, um zu ändern. Selbst PUT und DELETE wurden mit POST ausgeführt. Die Frage, was PUT wirklich bedeutet, 25 Jahre später zu stellen, könnte ein Zeichen dafür sein, dass wir es zuerst falsch gelernt haben. Die Beliebtheit von REST hat die Menschen zurück zu den Grundlagen geführt, wo wir jetzt frühere Fehler verlernen müssen. POST wurde übermäßig verwendet und wird jetzt häufig falsch gelehrt. Bester Teil: "Zweimal POSTen mit den gleichen Daten bedeutet, zwei identische [Ressourcen] zu erstellen". Toller Punkt!

2 Stimmen

Wie können Sie PUT verwenden, um einen Datensatz anhand der ID zu erstellen, wie in Ihrem Beispiel Benutzer 5, wenn er noch nicht vorhanden ist? Meinen Sie nicht aktualisieren, ersetzen, wenn bereits vorhanden oder Ähnliches?

0 Stimmen

@Coulton: Ich meine, was ich geschrieben habe. Du fügst Benutzer 5 ein, wenn du PUT auf /users/5 setzt und #5 noch nicht existiert.

290voto

7hi4g0 Punkte 3479

Zusammenfassung:

Erstellen:

Kann auf folgende Weise sowohl mit PUT als auch mit POST durchgeführt werden:

PUT

Erstellt die neue Ressource mit newResourceId als Kennung unter der URI /resources oder in der Sammlung.

PUT /resources/ HTTP/1.1

POST

Erstellt eine neue Ressource unter der URI /resources oder in der Sammlung. Normalerweise wird die Kennung vom Server zurückgegeben.

POST /resources HTTP/1.1

Aktualisieren:

Kann nur auf folgende Weise mit PUT durchgeführt werden:

PUT

Aktualisiert die Ressource mit existingResourceId als Kennung unter der URI /resources oder in der Sammlung.

PUT /resources/ HTTP/1.1

Erklärung:

Wenn es um REST und URIs im Allgemeinen geht, haben Sie auf der linken Seite generische und auf der rechten Seite spezifische Elemente. Die generischen werden normalerweise als Sammlungen bezeichnet und die spezifischeren Elemente als Ressourcen. Beachten Sie, dass eine Ressource eine Sammlung enthalten kann.

Beispiele:

<-- generisch -- spezifisch -->

URI: website.example/users/john
website.example  - ganze Website
users        - Sammlung von Benutzern
john         - Element der Sammlung oder Ressource

URI:website.example/users/john/posts/23
website.example  - ganze Website
users        - Sammlung von Benutzern
john         - Element der Sammlung oder Ressource
posts        - Sammlung von Beiträgen von john
23           - Beitrag von john mit Kennung 23, auch eine Ressource

Wenn Sie POST verwenden, beziehen Sie sich immer auf eine Sammlung, daher wenn Sie sagen:

POST /users HTTP/1.1

fügen Sie einen neuen Benutzer zur Benutzer-Sammlung hinzu.

Wenn Sie etwas wie dies versuchen:

POST /users/john HTTP/1.1

wird es funktionieren, aber semantisch gesehen sagen Sie, dass Sie eine Ressource zur john-Sammlung unter der Benutzer-Sammlung hinzufügen möchten.

Sobald Sie PUT verwenden, beziehen Sie sich auf eine Ressource oder ein einzelnes Element, möglicherweise innerhalb einer Sammlung. Wenn Sie also sagen:

PUT /users/john HTTP/1.1

sagen Sie dem Server, die john-Ressource unter der Benutzer-Sammlung zu aktualisieren oder zu erstellen, falls sie nicht existiert.

Spezifikation:

Lassen Sie mich einige wichtige Teile der Spezifikation hervorheben:

POST

Die POST-Methode wird verwendet, um vom Ursprungsserver zu fordern, dass die im Request eingebettete Entität als neuer untergeordneter der durch die Request-URI in der Request-Line identifizierten Ressource akzeptiert wird.

Erstellt also eine neue Ressource in einer Sammlung.

PUT

Die PUT-Methode fordert, dass die eingebettete Entität unter der mit der Request-URI bereitgestellten Adresse gespeichert wird. Wenn die Request-URI auf eine bereits vorhandene Ressource verweist, sollte die eingebettete Entität als eine modifizierte Version derjenigen auf dem Ursprungsserver betrachtet werden. Wenn die Request-URI nicht auf eine vorhandene Ressource verweist und diese URI als neue Ressource durch den anfordernden User-Agent definiert werden kann, kann der Ursprungsserver die Ressource unter dieser URI erstellen.

Erstellt oder aktualisiert also je nach Existenz der Ressource.

Referenz:

19 Stimmen

Dieser Beitrag war für mich hilfreich, um zu verstehen, dass POST "etwas" als Kind zur gegebenen Sammlung (URI) hinzufügt, während PUT "etwas" explizit an der angegebenen URI-Position definiert.

0 Stimmen

Es ist eine sehr vernünftige Möglichkeit, eine CRUD-API umzusetzen, die REST/HTTP-konform ist. Eine gute Lektüre: das RFC über HTTP, und besonders was idempotent ist und das erwartete Verhalten des Webcaches. Die Verwendung von POST/PUT wird durch das erwartete Verhalten des Caches (Web oder Benutzeragent) eingeschränkt.

5 Stimmen

Nein, PUT ist nicht für Aktualisierung oder Erstellung. Es dient zum Ersetzen. Beachten Sie, dass Sie mit PUT auch nichts durch etwas ersetzen können, um den Effekt der Erstellung zu erzielen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X