wake-up-neo.com

PUT vs. POST in REST

Gemäß der HTTP/1.1-Spezifikation:

Mit der Methode POST wird angefordert, dass der Origin-Server die in der Anforderung enthaltene Entität als neuen Untergebenen der Ressource akzeptiert, die durch _Request-URI_ in _Request-Line_ angegeben ist.

Mit anderen Worten, POST wird verwendet, um create.

Die Methode PUT fordert an, dass die eingeschlossene Entität unter dem angegebenen _Request-URI_ gespeichert wird. Wenn sich der _Request-URI_ auf eine bereits vorhandene Ressource bezieht, MUSS die beigefügte Entität als eine modifizierte Version der Entität auf dem Origin-Server betrachtet werden. Wenn der _Request-URI_ nicht auf eine vorhandene Ressource verweist und dieser URI vom anfordernden Benutzeragenten als neue Ressource definiert werden kann, kann der Origin-Server die Ressource mit diesem URI erstellen. "

Das heißt, PUT wird zum Erstellen oder Aktualisieren verwendet.

Also, welches sollte man verwenden, um eine Ressource zu erstellen? Oder muss man beides unterstützen?

5105
alex

Insgesamt:

Zum Erstellen können sowohl PUT als auch POST verwendet werden.

Sie müssen fragen: "Wofür führen Sie die Aktion aus?" zu unterscheiden, was Sie verwenden sollten. Angenommen, Sie entwerfen eine API zum Stellen von Fragen. Wenn Sie POST verwenden möchten, würden Sie dies mit einer Liste von Fragen tun. Wenn Sie PUT verwenden möchten, würden Sie dies für eine bestimmte Frage tun.

Großartig, beide können verwendet werden, also welche sollte ich in meinem RESTful-Design verwenden:

Sie müssen weder PUT noch POST unterstützen.

Was verwendet wird, bleibt Ihnen überlassen. Denken Sie jedoch daran, das richtige Objekt zu verwenden, je nachdem, auf welches Objekt Sie in der Anfrage verweisen.

Einige Überlegungen:

  • Benennen Sie Ihre URL-Objekte, die Sie explizit erstellen, oder lassen Sie den Server entscheiden? Wenn Sie sie benennen, verwenden Sie PUT. Wenn Sie den Server entscheiden lassen, verwenden Sie POST.
  • PUT ist idempotent. Wenn Sie also ein Objekt zweimal PUTEN, hat dies keine Auswirkung. Dies ist eine nette Eigenschaft, also würde ich PUT verwenden, wenn es möglich ist.
  • Sie können eine Ressource mit PUT mit derselben Objekt-URL aktualisieren oder erstellen
  • Mit POST können zwei Anforderungen gleichzeitig eingehen, um Änderungen an einer URL vorzunehmen, und sie können verschiedene Teile des Objekts aktualisieren.

Ein Beispiel:

Ich habe folgendes als Teil einer anderen Antwort auf SO geschrieben :

POST:

Dient zum Ändern und Aktualisieren einer Ressource

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

Beachten Sie, dass Folgendes ein Fehler ist:

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

Wenn die URL noch nicht erstellt wurde, sollten Sie sie nicht mit POST erstellen, während Sie den Namen angeben. Dies sollte zu einem Fehler "Ressource nicht gefunden" führen, da <new_question> noch nicht vorhanden ist. Sie sollten zuerst die Ressource <new_question> auf den Server stellen.

Sie können jedoch wie folgt vorgehen, um mithilfe von POST Ressourcen zu erstellen:

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

Beachten Sie, dass in diesem Fall der Ressourcenname nicht angegeben wird und der URL-Pfad des neuen Objekts an Sie zurückgegeben wird.

PUT:

Dient zum Erstellen oder Überschreiben einer Ressource. Während Sie die Ressourcen angeben, gibt es eine neue URL.

Für eine neue Ressource:

PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/

So überschreiben Sie eine vorhandene Ressource:

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/
4018
Brian R. Bondy

Im Internet finden Sie Aussagen, die besagen, dass

Weder ist ganz richtig.


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

PUT bedeutet, eine Ressource zu platzieren und alles, was unter der angegebenen URL verfügbar ist, vollständig durch eine andere zu ersetzen. Per Definition ist ein PUT idempotent. Mache es so oft du willst und das Ergebnis ist dasselbe. x=5 ist idempotent. Sie können eine Ressource PUTEN, unabhängig davon, ob sie bereits vorhanden ist oder nicht (z. B. zum Erstellen oder Aktualisieren)!

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


Mit diesem Argument wird PUT erstellt, wenn Sie die URL des zu erstellenden Objekts kennen. POST kann zum Erstellen verwendet werden, wenn Sie die URL der "Factory" oder des Managers für die Kategorie von Dingen kennen, die Sie erstellen möchten.

damit:

POST /expense-report

oder:

PUT  /expense-report/10929
2111
Cheeso
  • POST to a URL erstellt eine untergeordnete Ressource at a server defined URL.
  • PUT to a URL erstellt/ersetzt die Ressource vollständig an der vom Client definierten URL.
  • PATCH zu einer URL aktualisiert einen Teil der Ressource zu dieser vom Client definierten URL.

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

POST erstellt eine untergeordnete Ressource, daher erstellt POST bis /items Ressourcen, die sich unter der Ressource /items befinden. Z.B. /items/1. Wenn Sie dasselbe Post-Paket zweimal senden, werden zwei Ressourcen erstellt.

PUT dient zum Erstellen oder Ersetzen einer Ressource unter einer dem Client bekannten URL.

Deshalb: PUT ist nur ein Kandidat für CREATE, bei dem der Client die URL bereits kennt, bevor die Ressource erstellt wird. Z.B. /blogs/nigel/entry/when_to_use_post_vs_put als Titel wird als Ressourcenschlüssel verwendet

PUT ersetzt die Ressource unter der bekannten URL, wenn diese bereits vorhanden ist, sodass das zweimalige Senden derselben Anforderung keine Auswirkung hat. Mit anderen Worten, PUT-Aufrufe sind idempotent.

Der RFC lautet wie folgt:

Der grundlegende Unterschied zwischen den Anforderungen POST und PUT spiegelt sich in der unterschiedlichen Bedeutung der Anforderungs-URI wider. Der URI in einer POST -Anforderung gibt die Ressource an, die die eingeschlossene Entität verarbeiten soll. Diese Ressource kann ein datenakzeptierender Prozess, ein Gateway zu einem anderen Protokoll oder eine separate Entität sein, die Anmerkungen akzeptiert. Im Gegensatz dazu identifiziert der URI in einer PUT-Anforderung die Entität, die der Anforderung beigefügt ist - der Benutzeragent weiß, welche URI beabsichtigt ist, und der Server darf NICHT versuchen, die Anforderung auf eine andere Ressource anzuwenden. Wenn der Server wünscht, dass die Anforderung auf einen anderen URI angewendet wird,

Anmerkung: PUT wurde hauptsächlich zum Aktualisieren von Ressourcen verwendet (indem sie vollständig ersetzt wurden). In letzter Zeit wird jedoch PATCH zum Aktualisieren vorhandener Ressourcen verwendet, da PUT angibt, dass es die gesamte Ressource ersetzt. RFC 5789

pdate 2018: Es gibt einen Fall, bei dem PUT vermieden werden kann. Siehe "REST without PUT"

Mit der Technik "REST without PUT" müssen Verbraucher neue "nominierte" Anforderungsressourcen bereitstellen. Wie bereits erwähnt, handelt es sich beim Ändern der Postanschrift eines Kunden um eine POST in eine neue Ressource "ChangeOfAddress", nicht um einen PUT einer Ressource "Customer" mit einem anderen Feldwert für die Postanschrift.

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

Dies zwingt die API, Probleme beim Statuswechsel zu vermeiden, wenn mehrere Clients eine einzelne Ressource aktualisieren, und passt besser zu Event-Sourcing und CQRS. Wenn die Arbeit asynchron erledigt ist, erscheint es angemessen, die Umwandlung zu POSTEN und darauf zu warten, dass sie angewendet wird.

668
Nigel Thorne

Zusammenfassung:

Erstellen:

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

STELLEN

Erstellt DIE neue Ressource mit newResourceId als Bezeichner unter/resources URI oder Sammlung .

PUT /resources/<newResourceId> HTTP/1.1 

POST

Erstellt EINE neue Ressource unter der/resources-URI oder -Auflistung . Normalerweise wird die Kennung vom Server zurückgegeben.

POST /resources HTTP/1.1

Aktualisieren:

Kann mit PUT nur folgendermaßen ausgeführt werden:

STELLEN

Aktualisiert die Ressource mit existingResourceId als Bezeichner unter dem URI/resources oder der Auflistung .

PUT /resources/<existingResourceId> HTTP/1.1

Erläuterung:

Wenn Sie sich mit REST und URI als allgemein befassen, haben Sie generisches auf left und spezifisch auf dem rechts . Die Generika werden üblicherweise als Sammlungen und die weiteren Bestimmte Gegenstände können als Ressource bezeichnet werden. Beachten Sie, dass eine Ressource eine Auflistung enthalten kann.

Beispiele:

<- generisch - spezifisch ->

URI: website.com/users/john
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource

URI:website.com/users/john/posts/23
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource
posts        - collection of posts from john
23           - post from john with identifier 23, also a resource

Wenn Sie POST verwenden, beziehen Sie sich immer auf eine Sammlung , also wann immer du sagst:

POST /users HTTP/1.1

sie veröffentlichen einen neuen Benutzer in der Sammlung users .

Wenn Sie weitermachen und so etwas ausprobieren:

POST /users/john HTTP/1.1

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

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

PUT /users/john HTTP/1.1

sie teilen dem Server-Update mit oder erstellen, falls es nicht vorhanden ist, die Ressource john unter der Benutzer Sammlung .

Spec:

Lassen Sie mich einige wichtige Teile der Spezifikation hervorheben:

POST

Die Methode POST wird verwendet, um anzufordern, dass der Origin-Server akzeptiert Die Entität, die in der Anforderung als new untergeordnet der durch den Anforderungs-URI in angegebenen Ressource enthalten ist die Request-Line

Erstellt daher eine neue Ressource für eine Auflistung .

STELLEN

Die PUT - Methode fordert an, dass die eingeschlossene Entität unter dem gespeichert wird gelieferte Request-URI. Wenn der Request-URI auf eine bereits vorhandene Ressource verweist, MUSS die beigefügte Entität als modifizierte Version betrachtet werden desjenigen, der sich auf dem Origin-Server befindet. Wenn der Request-URI nicht auf eine vorhandene Ressource verweist und dieser URI fähig ist vom anfordernden Benutzeragenten, dem Origin-Server, als new Ressource definiert zu werden kann die Ressource mit dieser URI erstellen . "

Erstellen oder aktualisieren Sie daher basierend auf dem Vorhandensein der Ressource .

Referenz:

204
7hi4g0

Ich möchte meinen "pragmatischen" Rat hinzufügen. Verwenden Sie PUT, wenn Sie die "ID" kennen, mit der das zu speichernde Objekt abgerufen werden kann. Die Verwendung von PUT wird nicht allzu gut funktionieren, wenn Sie beispielsweise eine von einer Datenbank generierte ID benötigen, die Sie für zukünftige Suchvorgänge oder Aktualisierungen zurückgeben können.

So speichern Sie einen vorhandenen Benutzer oder einen Benutzer, bei dem der Client die ID generiert und überprüft hat, dass die ID eindeutig ist:

PUT /user/12345 HTTP/1.1  <-- create the user providing the id 12345
Host: mydomain.com

GET /user/12345 HTTP/1.1  <-- return that user
Host: mydomain.com

Verwenden Sie andernfalls POST, um das Objekt zu Beginn zu erstellen, und PUT, um das Objekt zu aktualisieren:

POST /user HTTP/1.1   <--- create the user, server returns 12345
Host: mydomain.com

PUT /user/12345 HTTP/1.1  <--- update the user
Host: mydomain.com
170
ThaDon

POST bedeutet "neu erstellen" wie in "Hier ist die Eingabe zum Erstellen eines Benutzers, erstellen Sie es für mich".

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

Sie POST an example.com/users, da Sie die URL des Benutzers noch nicht kennen, möchten, dass der Server sie erstellt.

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

Durch zweimaliges POSTING mit denselben Daten werden zwei identische Benutzer mit unterschiedlichen IDs erstellt. Durch zweimaliges PUT mit denselben Daten wird der erste Benutzer erstellt und beim zweiten Mal auf denselben Status aktualisiert (keine Änderungen). Da Sie nach einem PUT immer denselben Zustand haben, egal wie oft Sie es ausführen, wird es jedes Mal als "gleich stark" bezeichnet - idempotent. Dies ist nützlich, um Anfragen automatisch zu wiederholen. Nicht mehr "Sind Sie sicher, dass Sie erneut senden möchten", wenn Sie die Zurück-Taste im Browser drücken.

Es wird allgemein empfohlen, POST zu verwenden, wenn der Server die URL-Generierung Ihrer Ressourcen steuern soll. Verwenden Sie ansonsten PUT. Ziehen Sie PUT POST vor.

164

Verwenden Sie POST zum Erstellen und PUT zum Aktualisieren. So macht es jedenfalls Ruby on Rails.

PUT    /items/1      #=> update
POST   /items        #=> create
122
Tim Sullivan

Beide werden für die Datenübertragung zwischen Client und Server verwendet, unterscheiden sich jedoch geringfügig in folgenden Punkten:

Enter image description here

Analogie:

  • PUT, d.h. take und put wo es war.
  • POST als E-Mail senden in Post Büro.

enter image description here

Social Media/Netzwerk Analogie:

  • Post in den sozialen Medien: Wenn wir eine Nachricht posten, wird ein neuer Beitrag erstellt.
  • Setzen Sie (d. H. Bearbeiten) für die Nachricht, die wir bereits veröffentlicht haben.
104
Premraj

REST ist ein sehr übergeordnetes Konzept. Tatsächlich wird HTTP überhaupt nicht erwähnt!

Wenn Sie Zweifel daran haben, wie REST in HTTP implementiert werden soll, können Sie sich immer die Spezifikation Atom Publication Protocol (AtomPub) ansehen. AtomPub ist ein Standard zum Schreiben von REST-fähigen Webservices mit HTTP, der von vielen HTTP- und REST -Lights entwickelt wurde, wobei Roy Fielding, der Erfinder von REST und (Mit-) Erfinder von HTTP selbst, einige Beiträge leistete.

Möglicherweise können Sie AtomPub sogar direkt verwenden. Obwohl es aus der Blog-Community stammt, ist es keineswegs auf das Bloggen beschränkt: Es ist ein generisches Protokoll für die REST-gerechte Interaktion mit beliebigen (verschachtelten) Sammlungen beliebiger Ressourcen über HTTP. Wenn Sie Ihre Anwendung als verschachtelte Ressourcensammlung darstellen können, müssen Sie nur AtomPub verwenden und sich keine Gedanken darüber machen, ob PUT oder POST verwendet werden soll, welche HTTP-Statuscodes zurückgegeben werden sollen und all diese Details.

Das sagt AtomPub zur Erstellung von Ressourcen (Abschnitt 9.2):

Um Mitglieder zu einer Sammlung hinzuzufügen, senden Clients POST - Anforderungen an den URI der Sammlung.

65
Jörg W Mittag

Die Entscheidung, ob eine Ressource mit PUT oder POST auf einem Server mit einer HTTP + REST-API erstellt wird, hängt davon ab, wem die URL gehört Struktur. Wenn der Client die URL-Struktur kennt oder daran teilnimmt, ist dies eine unnötige Kopplung, die den unerwünschten Kopplungen ähnelt, die durch SOA entstanden sind. Das Entkommen von Kupplungstypen ist der Grund, warum REST so beliebt ist. Daher ist POST die geeignete Methode. Es gibt Ausnahmen zu dieser Regel, und sie treten auf, wenn der Client die Kontrolle über die Standortstruktur des POST behalten möchte bereitgestellte Ressourcen. Dies ist selten und bedeutet wahrscheinlich, dass etwas anderes nicht stimmt.

An diesem Punkt werden einige Leute argumentieren, dass, wenn RESTful-URLs verwendet werden, der Client die URL der Ressource kennt und daher ein PUT akzeptabel ist. Aus diesem Grund sind kanonische, normalisierte, Ruby on Rails, Django URLs wichtig. Schauen Sie sich die Twitter-API an… bla bla bla. Diese Leute müssen verstehen , dass es keine Restful-URL gibt und dass Roy Fielding selbst feststellt, dass :

Eine REST API darf keine festen Ressourcennamen oder -hierarchien definieren (eine offensichtliche Kopplung von Client und Server). Server müssen die Freiheit haben, ihren eigenen Namespace zu steuern. Ermöglichen Sie Servern stattdessen, Clients Anweisungen zum Erstellen geeigneter URIs zu erteilen, z. B. in HTML-Formularen und URI-Vorlagen, indem Sie diese Anweisungen in Medientypen und Verknüpfungsbeziehungen definieren. [Ein Misserfolg impliziert hier, dass Clients aufgrund von Out-of-Band-Informationen eine Ressourcenstruktur annehmen, wie z. B. einen domänenspezifischen Standard, der das datenorientierte Äquivalent zur funktionalen Kopplung von RPC darstellt.].

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Die Idee einer RESTful-URL ist eine Verletzung von REST, da der Server für die URL-Struktur verantwortlich ist und frei entscheiden sollte, wie er verwendet werden soll es, um eine Kopplung zu vermeiden. Wenn dies verwirrt, lesen Sie die Bedeutung der Selbsterkennung für das API-Design.

Die Verwendung von POST zum Erstellen von Ressourcen ist mit einer Überlegung zum Design verbunden, da POST nicht idempotent ist. Dies bedeutet, dass eine Wiederholung erfolgt Ein mehrmaliges POST garantiert nicht immer das gleiche Verhalten. Dies erschreckt Leute, PUT zu verwenden, um Ressourcen zu erstellen, wenn sie es nicht sollten. Sie wissen, dass es falsch ist (POST ist für CREATE), aber sie tun es trotzdem, weil sie nichts tun weiß nicht, wie man dieses Problem löst. Dieses Anliegen wird in der folgenden Situation gezeigt:

  1. Der Client POST eine neue Ressource auf dem Server.
  2. Der Server verarbeitet die Anfrage und sendet eine Antwort.
  3. Der Client erhält nie die Antwort.
  4. Dem Server ist nicht bekannt, dass der Client die Antwort nicht erhalten hat.
  5. Der Client hat keine URL für die Ressource (daher ist PUT keine Option) und wiederholt den POST.
  6. POST ist nicht idempotent und der Server ...

In Schritt 6 werden die Leute häufig verwirrt, was zu tun ist. Es gibt jedoch keinen Grund, einen Kludge zu erstellen, um dieses Problem zu lösen. Stattdessen kann HTTP wie in RFC 2616 angegeben verwendet werden, und der Server antwortet:

10.4.10 409 Konflikt

Die Anforderung konnte aufgrund eines Konflikts mit dem aktuellen Status der Ressource nicht abgeschlossen werden. Dieser Code ist nur in Situationen zulässig, in denen erwartet wird, dass der Benutzer den Konflikt möglicherweise lösen und die Anforderung erneut senden kann. Der Antwortkörper sollte genug enthalten

informationen, mit denen der Benutzer die Ursache des Konflikts erkennen kann. Im Idealfall würde die Antwortentität genügend Informationen enthalten, damit der Benutzer oder Benutzeragent das Problem beheben kann. Dies ist jedoch möglicherweise nicht möglich und nicht erforderlich.

Konflikte treten am wahrscheinlichsten als Reaktion auf eine PUT-Anforderung auf. Wenn beispielsweise die Versionierung verwendet wird und die Entität, die PUT ist, Änderungen an einer Ressource enthält, die mit den von einer früheren (Drittanbieter-) Anforderung vorgenommenen Konflikten in Konflikt stehen, verwendet der Server möglicherweise die Antwort 409, um anzuzeigen, dass die Anforderung nicht abgeschlossen werden kann . In diesem Fall enthält die Antwortentität wahrscheinlich eine Liste der Unterschiede zwischen den beiden Versionen in einem Format, das durch den Inhaltstyp der Antwort definiert wird.

Antworten mit einem Statuscode von 409 Konflikt ist der richtige Rückgriff, weil :

  • Das Durchführen eines POST von Daten mit einer ID, die mit einer bereits im System vorhandenen Ressource übereinstimmt, ist „ein Konflikt mit dem aktuellen Status der Ressource“.
  • Da es für den Client wichtig ist, zu verstehen, dass der Server über die Ressource verfügt, und geeignete Maßnahmen zu ergreifen. Dies ist eine Situation, in der erwartet wird, dass der Benutzer den Konflikt möglicherweise lösen und die Anforderung erneut senden kann.
  • Eine Antwort, die die URL der Ressource mit der in Konflikt stehenden ID und den entsprechenden Voraussetzungen für die Ressource enthält, würde "genügend Informationen für den Benutzer oder den Benutzeragenten bereitstellen, um das Problem zu beheben", was gemäß RFC 2616 der Idealfall ist.

Update basierend auf dem Release von RFC 7231 to Replace 2616

RFC 7231 ersetzt 2616 und beschreibt in Abschnitt 4.3. die folgende mögliche Antwort für einen POST

Wenn das Ergebnis der Verarbeitung eines POST einer Darstellung einer vorhandenen Ressource entspricht, KANN ein Origin-Server den Benutzeragenten an diese Ressource umleiten, indem er eine 303-Antwort (siehe Andere) mit der Kennung der vorhandenen Ressource in sendet das Feld Ort. Dies hat den Vorteil, dass dem Benutzeragenten eine Ressourcenkennung bereitgestellt und die Darstellung über eine Methode übertragen wird, die für das gemeinsame Zwischenspeichern besser geeignet ist, allerdings auf Kosten einer zusätzlichen Anforderung, wenn der Benutzeragent die Darstellung noch nicht zwischengespeichert hat.

Es ist jetzt vielleicht verlockend, einfach einen 303 zurückzugeben, falls ein POST wiederholt wird. Das Gegenteil ist jedoch der Fall. Die Rückgabe einer 303 ist nur dann sinnvoll, wenn mehrere Erstellungsanforderungen (Erstellen unterschiedlicher Ressourcen) denselben Inhalt zurückgeben. Ein Beispiel wäre "Danke, dass Sie Ihre Anforderungsnachricht gesendet haben", die der Client nicht jedes Mal neu herunterladen muss. RFC 7231 behauptet weiterhin in Abschnitt 4.2.2, dass POST nicht idempotent sein soll, und behauptet weiterhin, dass POST zum Erstellen verwendet werden soll.

Weitere Informationen hierzu finden Sie in diesem Artikel .

59
Joshcodes

Ich mag diesen Rat aus RFC 2616's Definition von PUT :

Der grundlegende Unterschied zwischen den Anforderungen POST und PUT spiegelt sich in der unterschiedlichen Bedeutung der Anforderungs-URI wider. Der URI in einer POST -Anforderung gibt die Ressource an, die die eingeschlossene Entität verarbeiten soll. Diese Ressource kann ein datenakzeptierender Prozess, ein Gateway zu einem anderen Protokoll oder eine separate Entität sein, die Anmerkungen akzeptiert. Im Gegensatz dazu identifiziert der URI in einer PUT-Anforderung die Entität, die der Anforderung beigefügt ist - der Benutzeragent weiß, welche URI beabsichtigt ist, und der Server darf NICHT versuchen, die Anforderung auf eine andere Ressource anzuwenden.

Dies stimmt mit dem anderen Rat überein, dass PUT am besten auf Ressourcen angewendet wird, die bereits einen Namen haben, und POST ist gut zum Erstellen eines neuen Objekts unter einer vorhandenen Ressource (und zum Benennen durch den Server).

Ich interpretiere dies und die Idempotenzanforderungen an PUT so, dass:

  • POST eignet sich zum Erstellen neuer Objekte unter einer Sammlung (und create muss nicht idempotent sein).
  • PUT ist gut für die Aktualisierung vorhandener Objekte (und die Aktualisierung muss idempotent sein)
  • POST kann auch für nicht-idempotente Aktualisierungen vorhandener Objekte verwendet werden (insbesondere zum Ändern eines Teils eines Objekts ohne Angabe des Ganzen). Wenn Sie darüber nachdenken, ist das Erstellen eines neuen Mitglieds einer Sammlung ein besonderer Fall dieser Art Update, aus Sicht der Sammlung)
  • PUT kann auch zum Erstellen verwendet werden, wenn Sie dem Client erlauben, die Ressource zu benennen. Da jedoch REST Clients keine Annahmen über die URL-Struktur treffen sollen, ist dies weniger im beabsichtigten Sinn der Dinge.
53
metamatt

Zusamenfassend:

PUT ist idempotent, wobei der Ressourcenzustand gleich ist, wenn dieselbe Operation ein- oder mehrmals ausgeführt wird.

POST ist nicht idempotent, wobei sich der Ressourcenzustand ändern kann, wenn die Operation im Vergleich zur einmaligen Ausführung mehrmals ausgeführt wird.

Analogie zur Datenbankabfrage

PUT Sie können ähnlich wie "UPDATE STUDENT SET address =" abc "denken, wobei id =" 123 ";

POST Sie können an etwas wie "INSERT INTO STUDENT (Name, Adresse) VALUES (" abc "," xyzzz ") denken;

Die Schüler-ID wird automatisch generiert.

Wenn dieselbe Abfrage bei PUT mehrmals oder einmal ausgeführt wird, bleibt der Status der Tabelle STUDENT unverändert.

Wenn dieselbe Abfrage beim POST mehrmals ausgeführt wird, werden mehrere Schülerdatensätze in der Datenbank erstellt, und der Datenbankstatus ändert sich bei jeder Ausführung einer "EINFÜGEN" -Abfrage.

ANMERKUNG: PUT benötigt einen Ressourcenspeicherort (bereits Ressource), auf dem eine Aktualisierung erfolgen muss, während POST dies nicht erfordert. Daher ist POST intuitiv für die Erstellung einer neuen Ressource gedacht, während PUT für die Aktualisierung der bereits vorhandenen Ressource benötigt wird.

Es kann vorkommen, dass Aktualisierungen mit POST durchgeführt werden können. Es gibt keine feste Regel, welche für Aktualisierungen oder welche zum Erstellen verwendet werden soll. Auch dies sind Konventionen, und intuitiv bin ich mit der oben genannten Argumentation geneigt und folge ihr.

46
bharatj

Beim POST wird ein Brief an eine Mailbox gesendet oder eine E-Mail an eine E-Mail-Warteschlange gesendet. PUT entspricht dem Platzieren eines Objekts in einem Ablagefach oder in einem Regal (die Adresse ist bekannt).

Mit POST senden Sie eine Nachricht an die Adresse der QUEUE oder COLLECTION. Mit PUT rufen Sie die Adresse des EINZELTEILS auf.

Put ist idempotent. Sie können die Anfrage 100 Mal senden und es spielt keine Rolle. POST ist nicht idempotent. Wenn Sie die Anfrage 100 Mal senden, erhalten Sie 100 E-Mails oder 100 Briefe in Ihrem Postfach.

Eine allgemeine Regel: Wenn Sie die ID oder den Namen des Elements kennen, verwenden Sie PUT. Wenn Sie möchten, dass die ID oder der Name des Artikels von der empfangenden Partei zugewiesen wird, verwenden Sie POST.

POST versus PUT

42
Homer6

Neue Antwort (jetzt, wo ich REST besser verstehe):

PUT ist lediglich eine Aussage darüber, welche Inhalte der Dienst von nun an verwenden soll, um Darstellungen der vom Kunden identifizierten Ressource wiederzugeben. POST ist eine Aussage darüber, welche Inhalte der Dienst von nun an enthalten soll (möglicherweise dupliziert), aber es liegt an dem Server, wie dieser Inhalt identifiziert wird.

PUT x (wenn x ein Ressource identifiziert): "Ersetzen Sie den Inhalt der durch x identifizierten Ressource durch meinen Inhalt."

PUT x (wenn x keine Ressource identifiziert): "Erstelle eine neue Ressource mit meinem Inhalt und benutze x, um sie zu identifizieren."

POST x: "Speichern Sie meinen Inhalt und geben Sie mir eine Kennung, mit der ich eine Ressource (alt oder neu) identifizieren kann, die diesen Inhalt enthält (möglicherweise gemischt mit anderen Inhalten). Diese Ressource sollte mit der Ressource identisch oder dieser untergeordnet sein, die x identifiziert. " "Die Ressource von y ist der Ressource von x untergeordnet" wird normalerweise, aber nicht unbedingt implementiert, indem y zu einem Unterpfad von x (zB x = /foo und y = /foo/bar) und Ändern der Darstellung (en) von x 's Ressource, um die Existenz einer neuen Ressource wiederzugeben, z mit einem Hyperlink zu y s Ressource und einigen Metadaten. Nur Letzteres ist für ein gutes Design wirklich wichtig, da URLs in REST undurchsichtig sind - Sie sollten Hypermedia verwenden anstelle der clientseitigen URL-Erstellung, um den Service trotzdem zu durchlaufen .

In REST gibt es keine Ressource, die "Inhalt" enthält. Ich verweise als "Inhalt" auf Daten, die der Dienst verwendet, um Darstellungen konsistent wiederzugeben. Sie besteht normalerweise aus einigen verwandten Zeilen in einer Datenbank oder einer Datei (z. B. einer Bilddatei). Es ist Aufgabe des Dienstes, den Inhalt des Benutzers in etwas zu konvertieren, das der Dienst verwenden kann, z. Konvertieren einer JSON-Nutzlast in SQL-Anweisungen.

Originalantwort (möglicherweise besser lesbar) :

PUT /something (falls /something bereits existiert): "Nimm, was du bei /something hast, und ersetze es durch das, was ich dir gebe."

PUT /something (falls /something noch nicht existiert): "Nimm, was ich dir gebe und stelle es auf /something."

POST /something: "Nimm, was ich dir gebe, und lege es unter /something, solange du mir seine URL gibst, wenn du fertig bist."

38
Jordan

kurze Antwort:

Einfache Faustregel: Zum Erstellen POST und zum Aktualisieren PUT verwenden.

Lange Antwort:

POST:

  • POST wird verwendet, um Daten an den Server zu senden.
  • Nützlich, wenn die URL der Ressource unbekannt ist

STELLEN:

  • Mit PUT wird der Status an den Server übertragen
  • Nützlich, wenn die URL einer Ressource bekannt ist

Längere Antwort:

Um dies zu verstehen, müssen wir uns fragen, warum PUT erforderlich war und welche Probleme PUT zu lösen versuchte, die POST nicht konnten.

Aus Sicht der REST Architektur ist nichts von Bedeutung. Wir hätten auch ohne PUT leben können. Aber aus der Sicht eines Kundenentwicklers hat es sein/ihr Leben viel einfacher gemacht.

Vor PUT konnten die Clients die vom Server generierte URL nicht direkt kennen oder konnten nicht wissen, ob die an den Server zu sendenden Daten bereits aktualisiert wurden oder nicht. PUT hat den Entwickler von all diesen Kopfschmerzen befreit. PUT ist idempotent, PUT handhabt die Race-Bedingungen und PUT lässt den Client die URL auswählen.

37
ishandutta2007

Ruby auf Rails 4.0 verwendet die 'PATCH'-Methode anstelle von PUT, um Teilaktualisierungen durchzuführen.

RFC 5789 sagt über PATCH (seit 1995):

Eine neue Methode ist erforderlich, um die Interoperabilität zu verbessern und Fehler zu vermeiden. Die PUT-Methode ist bereits so definiert, dass eine Ressource mit einem vollständig neuen Textkörper überschrieben wird. Sie kann nicht für Teiländerungen wiederverwendet werden. Andernfalls können Proxys und Caches sowie Clients und Server hinsichtlich des Ergebnisses des Vorgangs verwirrt werden. POST wird bereits verwendet, jedoch ohne umfassende Interoperabilität (zum einen gibt es keine Standardmethode, um die Unterstützung von Patch-Formaten zu ermitteln). PATCH wurde in früheren HTTP-Spezifikationen erwähnt, aber nicht vollständig definiert.

" Edge Rails: PATCH ist die neue primäre HTTP-Methode für Updates " erklärt es.

35
germanlinux

Bei der Gefahr, das Gesagte noch einmal zu wiederholen, scheint es wichtig zu sein, sich daran zu erinnern, dass PUT impliziert, dass der Client steuert, was die URL ist wird am Ende sein, wenn eine Ressource erstellt wird. Ein Teil der Wahl zwischen PUT und POST hängt davon ab, wie sehr Sie dem Kunden vertrauen können, dass er korrekte, normalisierte Daten liefert ) _ url _ , die mit Ihrem URL-Schema übereinstimmen.

Wenn Sie dem Client nicht vollständig vertrauen können, dass er das Richtige tut, ist es sinnvoller, POST zu verwenden, um ein neues Element zu erstellen, und dann die URL in der Antwort an den Client zurückzusenden.

27
skillet-thief

Auf ganz einfache Weise nehme ich das Beispiel der Facebook-Timeline.

Fall 1: Wenn Sie etwas auf Ihrer Timeline veröffentlichen, handelt es sich um einen neuen Eintrag. In diesem Fall verwenden sie die Methode POST, da die Methode POST nicht idempotent ist.

Fall 2: Wenn Ihr Freund Ihren Beitrag zum ersten Mal kommentiert, wird dadurch auch ein neuer Eintrag in der Datenbank erstellt, sodass die POST -Methode verwendet wird.

Fall 3: Wenn Ihr Freund seinen Kommentar bearbeitet, hatte er in diesem Fall eine Kommentar-ID, sodass er einen vorhandenen Kommentar aktualisiert, anstatt einen neuen Eintrag in der Datenbank zu erstellen. Verwenden Sie daher für diese Art von Operation die PUT-Methode, da sie idempotent ist. *

Verwenden Sie in einer einzelnen Zeile POST, um einen neuen Eintrag in die Datenbank einzufügen, und PUT, um pdate = etwas in der Datenbank.

23
UniCoder

Die wichtigste Überlegung ist Zuverlässigkeit. Wenn eine Nachricht POST verloren geht, ist der Status des Systems undefiniert. Eine automatische Wiederherstellung ist nicht möglich. Bei PUT-Nachrichten ist der Status nur bis zur ersten erfolgreichen Wiederholung undefiniert.

Beispielsweise ist es möglicherweise keine gute Idee, Kreditkartentransaktionen mit POST zu erstellen.

Wenn Ihre Ressource automatisch generierte URIs enthält, können Sie PUT weiterhin verwenden, indem Sie einen generierten URI (der auf eine leere Ressource verweist) an den Client übergeben.

Einige andere Überlegungen:

  • POST macht zwischengespeicherte Kopien der gesamten enthaltenen Ressource ungültig (bessere Konsistenz)
  • PUT-Antworten können nicht zwischengespeichert werden, während es sich bei POST um Antworten handelt (Inhaltsspeicherort und Ablaufdatum erforderlich).
  • PUT wird weniger unterstützt von z.B. Java ME, ältere Browser, Firewalls
20
Hans Malherbe

Leser, die dieses Thema noch nicht kennen, werden beeindruckt sein von der endlosen Diskussion darüber, was Sie tun sollten und der relativen Abwesenheit von Erfahrungslektionen. Die Tatsache, dass REST dem SOAP "vorgezogen" wird, ist vermutlich ein hochrangiges Lernen aus Erfahrung, aber Güte müssen wir von dort aus Fortschritte gemacht haben? Es ist 2016. Roys Dissertation war im Jahr 2000. Was haben wir entwickelt? Hat es Spaß gemacht? War die Integration einfach? Zu unterstützen? Wird es den Aufstieg von Smartphones und flockigen Mobilfunkverbindungen bewältigen?

Nach ME sind reale Netzwerke unzuverlässig. Zeitlimit für Anforderungen. Verbindungen werden zurückgesetzt. Netzwerke fallen stunden- oder tagelang aus. Züge fahren mit mobilen Benutzern an Bord in Tunnel. Für jede gegebene Anfrage (wie gelegentlich in all diesen Diskussionen bestätigt) kann die Anfrage auf dem Weg ins Wasser fallen, oder die Antwort kann auf dem Rückweg ins Wasser fallen. nter diesen Umständen hat es mich immer ein wenig brutal und naiv empfunden, PUT-,POST- und DELETE-Anforderungen direkt an inhaltliche Ressourcen zu richten.

HTTP unternimmt nichts, um eine zuverlässige Vervollständigung der Anfrage-Antwort zu gewährleisten, und das ist auch in Ordnung, da dies die Aufgabe von netzwerkfähigen Anwendungen ist. Bei der Entwicklung einer solchen Anwendung können Sie durch die Rahmen springen, um PUT anstelle von POST zu verwenden, und dann durch mehrere Rahmen, um eine bestimmte Art von Fehler auf dem Server zu verursachen, wenn Sie doppelte Anforderungen feststellen. Zurück am Client müssen Sie dann durch die Rahmen springen, um diese Fehler zu interpretieren, erneut abzurufen, erneut zu validieren und erneut zu veröffentlichen.

Oder Sie können dies tun: Betrachten Sie Ihre unsicheren Anforderungen als kurzlebige Einzelbenutzerressourcen (nennen wir sie Aktionen). Clients fordern eine neue "Aktion" für eine inhaltliche Ressource mit einem leeren POST für die Ressource an. POST wird nur dafür verwendet. Sobald der Client sicher im Besitz der URI der frisch geprägten Aktion ist, sendet er die unsichere Anforderung an die Aktions-URI , nicht an die Zielressource . Das Auflösen der Aktion und das Aktualisieren der "echten" Ressource ist ordnungsgemäß Aufgabe Ihrer API und wird hier vom unzuverlässigen Netzwerk entkoppelt.

Der Server erledigt das Geschäft, gibt die Antwort zurück und speichert sie unter dem vereinbarten Aktions-URI . Wenn etwas schief geht, wiederholt der Client die Anfrage (natürliches Verhalten!), Und wenn der Server sie bereits gesehen hat, wiederholt er die gespeicherte Antwort und unternimmt nichts anderes .

Sie werden die Ähnlichkeit mit Versprechungen schnell erkennen: Wir erstellen und geben den Platzhalter für das Ergebnis zurück, bevor Sie etwas unternehmen. Ebenso wie ein Versprechen kann eine Aktion einmal erfolgreich sein oder scheitern, aber das Ergebnis kann wiederholt abgerufen werden.

Das Beste ist, wir geben sendenden und empfangenden Anwendungen die Möglichkeit, die eindeutig identifizierte Aktion mit der Eindeutigkeit in ihrer jeweiligen Umgebung zu verknüpfen. Und wir können anfangen, verantwortungsbewusstes Verhalten von Kunden einzufordern und durchzusetzen: Wiederholen Sie Ihre Anfragen so oft Sie möchten, aber generieren Sie keine neue Aktion, bis Sie im Besitz eines endgültigen Ergebnisses der bestehenden sind.

Als solche gehen zahlreiche dornige Probleme weg. Durch wiederholtes Einfügen werden keine Duplikate erstellt, und die eigentliche Ressource wird erst erstellt, wenn wir über die Daten verfügen. (Datenbankspalten können nicht nullwertfähig bleiben). Wiederholte Aktualisierungsanforderungen treffen nicht auf inkompatible Status und überschreiben nachfolgende Änderungen nicht. Clients können die ursprüngliche Bestätigung aus beliebigen Gründen (erneut) abrufen und nahtlos verarbeiten (Client abgestürzt, Antwort fehlgeschlagen usw.).

Aufeinanderfolgende Löschanforderungen können die ursprüngliche Bestätigung anzeigen und verarbeiten, ohne dass ein 404-Fehler auftritt. Wenn die Dinge länger dauern als erwartet, können wir vorläufig reagieren und haben einen Ort, an dem der Kunde nach dem endgültigen Ergebnis suchen kann. Der schönste Teil dieses Musters ist die Kung-Fu-Eigenschaft (Panda). Wir nehmen eine Schwäche, die Neigung der Kunden, eine Anfrage zu wiederholen, wenn sie die Antwort nicht verstehen, und machen daraus eine Stärke :-)

Bevor Sie mir sagen, dass dies nicht REST-konform ist, bedenken Sie bitte die zahlreichen Arten, in denen REST Prinzipien respektiert werden. Clients erstellen keine URLs. Die API bleibt auffindbar, wenn auch mit einer kleinen Änderung in der Semantik. HTTP-Verben werden entsprechend verwendet. Wenn Sie der Meinung sind, dass dies eine große Änderung ist, kann ich Ihnen aus Erfahrung sagen, dass dies nicht der Fall ist.

Wenn Sie der Meinung sind, dass Sie große Datenmengen speichern müssen, sprechen wir über das Volumen: Eine typische Aktualisierungsbestätigung ist ein Bruchteil eines Kilobytes. HTTP gibt Ihnen derzeit ein oder zwei Minuten Zeit, um definitiv zu antworten. Selbst wenn Sie nur eine Woche lang Aktionen speichern, haben Kunden reichlich Gelegenheit, auf dem Laufenden zu bleiben. Wenn Sie sehr hohe Volumes haben, möchten Sie möglicherweise einen dedizierten säurekompatiblen Schlüsselwertspeicher oder eine In-Memory-Lösung.

14
bbsimonbb

Zusätzlich zu den von anderen vorgeschlagenen Unterschieden möchte ich noch einen hinzufügen.

In der POST Methode können Sie Körperparameter in form-data senden.

In der PUT Methode müssen Sie Körperparameter in x-www-form-urlencoded senden

Header Content-Type:application/x-www-form-urlencoded

Dementsprechend können Sie in der PUT -Methode keine Dateien oder mehrteiligen Daten senden

EDIT

Der Inhaltstyp "application/x-www-form-urlencoded" ist ineffizient, um große Mengen von Binärdaten oder Text mit Nicht-ASCII-Zeichen zu senden. Der Inhaltstyp "Multipart/Formulardaten" sollte zum Senden von Formularen verwendet werden, die Dateien, Nicht-ASCII-Daten und Binärdaten enthalten.

Was bedeutet, wenn Sie einreichen müssen

dateien, Nicht-ASCII-Daten und Binärdaten

sie sollten POST Methode verwenden

14
Rohit Dhiman

Es scheint immer einige Verwirrung darüber zu geben, wann die HTTP-Methode POST im Vergleich zur HTTP-PUT-Methode für REST -Dienste verwendet werden soll. Die meisten Entwickler werden versuchen, CRUD-Operationen direkt mit HTTP-Methoden zu verknüpfen. Ich werde argumentieren, dass dies nicht korrekt ist und man die CRUD-Konzepte nicht einfach den HTTP-Methoden zuordnen kann. Das ist:

Create => HTTP PUT
Retrieve => HTTP GET
Update => HTTP POST
Delete => HTTP DELETE

Es ist richtig, dass die R(etrieve) und D(elete) der CRUD-Operationen direkt den HTTP-Methoden GET bzw. DELETE zugeordnet werden können. Die Verwirrung liegt jedoch in den Operationen C(reate) und U(update). In einigen Fällen kann der PUT zum Erstellen verwendet werden, während in anderen Fällen ein POST erforderlich ist. Die Mehrdeutigkeit liegt in der Definition einer HTTP-PUT-Methode gegenüber einer HTTP-POST-Methode.

Gemäß den HTTP 1.1-Spezifikationen müssen die Methoden GET, HEAD, DELETE und PUT idempotent sein, und die Methode POST ist nicht idempotent. Das heißt, eine Operation ist idempotent, wenn sie ein- oder mehrmals für eine Ressource ausgeführt werden kann und immer den gleichen Status dieser Ressource zurückgibt. Während eine nicht idempotente Operation einen geänderten Zustand der Ressource von einer Anforderung zu einer anderen zurückgeben kann. Daher gibt es bei einer nicht idempotenten Operation keine Garantie dafür, dass einer den gleichen Status einer Ressource erhält.

Basierend auf der obigen idempotenten Definition ist die Verwendung der HTTP-PUT-Methode im Vergleich zur Verwendung der HTTP-POST-Methode für REST -Dienste wie folgt: Verwenden Sie die HTTP-PUT-Methode, wenn:

The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee.
The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date).

In beiden Fällen können diese Vorgänge mehrmals mit denselben Ergebnissen ausgeführt werden. Das heißt, die Ressource wird nicht durch mehrmaliges Anfordern des Vorgangs geändert. Daher eine wahrhaft idempotente Operation. Verwenden Sie die Methode HTTP POST, wenn:

The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client.
On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation.

Fazit

Korrelieren und ordnen Sie CRUD-Operationen HTTP-Methoden für REST -Dienste nicht direkt zu. Die Verwendung einer HTTP-PUT-Methode im Vergleich zu einer HTTP-POST-Methode sollte auf dem idempotenten Aspekt dieser Operation basieren. Wenn die Operation idempotent ist, verwenden Sie die HTTP-PUT-Methode. Wenn die Operation nicht idempotent ist, verwenden Sie die Methode HTTP POST.

14
Burhan

der Origin-Server kann die Ressource mit diesem URI erstellen

Sie verwenden also POST und wahrscheinlich, aber nicht notwendiges PUT für die Ressourcenerstellung. Sie müssen nicht beide unterstützen. Für mich ist POST vollkommen genug. Es ist also eine Designentscheidung.

Wie in Ihrem Angebot erwähnt, verwenden Sie PUT zum Erstellen einer Ressource, die keinem IRI zugeordnet ist, und Sie möchten trotzdem eine Ressource erstellen. Zum Beispiel ersetzt PUT /users/123/password normalerweise das alte Passwort durch ein neues, aber Sie können es verwenden, um ein Passwort zu erstellen, falls es noch nicht existiert (zum Beispiel durch frisch registrierte Benutzer oder durch Wiederherstellung gesperrter Benutzer).

13
inf3rno

Ich werde mit folgendem landen:

PUT bezieht sich auf eine Ressource, die durch den URI identifiziert wird. In diesem Fall aktualisieren Sie es. Es ist der Teil der drei Verben, die sich auf Ressourcen beziehen - löschen und die anderen beiden werden.

POST ist im Grunde eine Freiformnachricht, deren Bedeutung als "außerhalb des Bandes" definiert wird. Wenn die Nachricht so interpretiert werden kann, dass eine Ressource zu einem Verzeichnis hinzugefügt wird, ist dies in Ordnung. Grundsätzlich müssen Sie jedoch die Nachricht verstehen, die Sie senden (veröffentlichen), um zu wissen, was mit der Ressource geschehen wird.


Da sich PUT, GET und DELETE auf eine Ressource beziehen, sind sie definitionsgemäß auch idempotent.

Der POST kann die anderen drei Funktionen ausführen, aber dann geht die Semantik der Anforderung auf den Intermediären wie Caches und Proxys verloren. Dies gilt auch für die Bereitstellung von Sicherheit für die Ressource, da der URI eines Posts nicht unbedingt die Ressource angibt, auf die er sich bezieht (kann es aber).

Ein PUT muss kein Create sein. Der Dienst kann einen Fehler verursachen, wenn die Ressource noch nicht erstellt wurde. Andernfalls wird sie aktualisiert. Oder umgekehrt: Möglicherweise wird die Ressource erstellt, Aktualisierungen sind jedoch nicht zulässig. Das einzige, was für PUT erforderlich ist, ist, dass es auf eine bestimmte Ressource verweist, und seine Nutzlast ist die Darstellung dieser Ressource. Ein erfolgreicher PUT bedeutet (mit Ausnahme von Interferenzen), dass ein GET dieselbe Ressource abruft.


Bearbeiten: Eine weitere Sache - ein PUT kann erstellen, aber wenn dies der Fall ist, muss die ID eine natürliche ID sein - AKA eine E-Mail-Adresse. Auf diese Weise ist beim zweimaligen PUT der zweite Put ein Update des ersten. Das macht es idempotent.

Wenn die ID generiert wird (z. B. eine neue Mitarbeiter-ID), erstellt der zweite PUT mit derselben URL einen neuen Datensatz, der gegen die idempotente Regel verstößt. In diesem Fall wäre das Verb POST, und die Nachricht (nicht die Ressource) würde darin bestehen, eine Ressource mit den in dieser Nachricht definierten Werten zu erstellen.

11
Gerard ONeill

Die Semantik soll sich dahingehend unterscheiden, dass "PUT" wie "GET" idempotent sein soll - das heißt, Sie können dieselbe exakte PUT-Anforderung mehrmals ausführen, und das Ergebnis sieht so aus, als ob Sie sie nur einmal ausgeführt hätten.

Ich werde die Konventionen beschreiben, die meiner Meinung nach am weitesten verbreitet und am nützlichsten sind:

Wenn Sie eine Ressource unter einer bestimmten URL PUTEN, wird sie unter dieser URL oder in einer ähnlichen Weise gespeichert.

Wenn Sie zu einer Ressource unter einer bestimmten URL POST wechseln, veröffentlichen Sie häufig eine verwandte Information zu dieser URL. Dies bedeutet, dass die Ressource unter der URL bereits vorhanden ist.

Wenn Sie beispielsweise einen neuen Stream erstellen möchten, können Sie ihn in eine URL einfügen. Wenn Sie jedoch eine Nachricht an einen vorhandenen Stream POST senden möchten, müssen Sie POST an dessen URL senden.

Zum Ändern der Eigenschaften des Streams können Sie entweder PUT oder POST verwenden. Verwenden Sie grundsätzlich nur "PUT", wenn die Operation idempotent ist - andernfalls verwenden Sie POST.

Beachten Sie jedoch, dass nicht alle modernen Browser andere HTTP-Verben als GET oder POST unterstützen.

9

Meistens werden Sie sie so verwenden:

  • POST eine Ressource in eine Sammlung
  • PUT eine durch collection /: id identifizierte Ressource

Zum Beispiel:

  • POST/items
  • PUT/items/1234

In beiden Fällen enthält der Anforderungshauptteil die Daten für die zu erstellende oder zu aktualisierende Ressource. Aus den Routennamen sollte ersichtlich sein, dass POST nicht idempotent ist (wenn Sie es dreimal aufrufen, werden drei Objekte erstellt), PUT jedoch idempotent ist (wenn Sie es dreimal aufrufen, ist das Ergebnis dasselbe). . PUT wird häufig für "Upsert" -Operationen (Erstellen oder Aktualisieren) verwendet. Sie können jedoch immer einen 404-Fehler zurückgeben, wenn Sie ihn nur zum Ändern verwenden möchten.

Beachten Sie, dass POST ein neues Element in der Auflistung "erstellt" und PUT ein Element an einer bestimmten URL "ersetzt". Es ist jedoch eine weit verbreitete Praxis, PUT für teilweise Änderungen zu verwenden, das heißt, es zu verwenden Nur um vorhandene Ressourcen zu aktualisieren und nur die enthaltenen Felder im Hauptteil zu ändern (die anderen Felder werden ignoriert). Dies ist technisch nicht korrekt. Wenn Sie REST-puristisch sein möchten, sollte PUT die gesamte Ressource ersetzen und Sie sollten PATCH für die Teilaktualisierung verwenden. Es ist mir persönlich egal, wie klar und konsistent das Verhalten auf all Ihren API-Endpunkten ist.

Denken Sie daran, dass REST eine Reihe von Konventionen und Richtlinien ist, um Ihre API einfach zu halten. Wenn Sie mit einer komplizierten Umgehung enden, nur um das Kästchen "RESTfull" zu markieren, dann haben Sie den Zweck verfehlt;)

7
tothemario

Während es wahrscheinlich eine agnostische Art gibt, diese zu beschreiben, scheint dies im Widerspruch zu verschiedenen Aussagen von Antworten auf Websites zu stehen.

Seien wir hier sehr klar und direkt. Wenn Sie ein .NET-Entwickler sind, der mit der Web-API arbeitet, sind die Fakten (aus der Microsoft-API-Dokumentation) http://www.asp.net/web-api/overview/creating-web-apis/creating) -a-Web-API-die-Crud-Operationen unterstützt :

1. PUT = UPDATE (/api/products/id)
2. MCSD Exams 2014 -  UPDATE = PUT, there are **NO** multiple answers for that question period.

Sicher können Sie "POST" zum Aktualisieren verwenden, aber befolgen Sie einfach die Konventionen, die für Sie mit Ihrem vorgegebenen Framework festgelegt wurden. In meinem Fall ist es .NET/Web API, also PUT ist für UPDATE gibt es keine Debatte.

Ich hoffe, dies hilft allen Microsoft-Entwicklern, die alle Kommentare mit Links zu Amazon- und Sun/Java-Websites lesen.

7
Tom Stickel

Hier ist eine einfache Regel:

PUT to a URL sollte verwendet werden, um die Ressource zu aktualisieren oder zu erstellen, die sich unter dieser URL befindet.

POST to a URL sollte verwendet werden, um eine Ressource zu aktualisieren oder zu erstellen, die sich unter einer anderen ("untergeordneten") URL befindet oder über HTTP nicht auffindbar ist.

6
Adam Griffiths

Wenn Sie mit Datenbankoperationen vertraut sind, gibt es

  1. Wählen
  2. Einfügen
  3. Aktualisieren
  4. Löschen
  5. Zusammenführen (Update falls bereits vorhanden, sonst einfügen)

Ich verwende PUT zum Zusammenführen und Aktualisieren ähnlicher Vorgänge und verwende POST für Einfügungen.

6
Rajan

In der Praxis eignet sich POST gut zum Erstellen von Ressourcen. Die URL der neu erstellten Ressource sollte im Location-Antwortheader zurückgegeben werden. PUT sollte zum vollständigen Aktualisieren einer Ressource verwendet werden. Bitte haben Sie Verständnis dafür, dass dies die bewährten Methoden beim Entwerfen einer RESTful-API sind. Die HTTP-Spezifikation als solche schränkt die Verwendung von PUT/POST mit einigen Einschränkungen für das Erstellen/Aktualisieren von Ressourcen nicht ein. Schauen Sie sich http://techoctave.com/c7/posts/71-Twitter-rest-api-dissected an, das die Best Practices zusammenfasst.

5
java_geek

POST: Verwenden Sie es zum Erstellen neuer Ressourcen. Es ist wie INSERT (SQL-Anweisung) mit einer automatisch inkrementierten ID. Im Antwortteil enthält es eine neu generierte ID.

Der POST wird auch zum Aktualisieren eines Datensatzes verwendet.

PUT: Verwenden Sie es zum Erstellen einer neuen Ressource, aber hier kenne ich den Identitätsschlüssel. Es ist wie bei INSERT (SQL-Anweisung), bei der ich den Identitätsschlüssel im Voraus kenne. Im Antwortteil sendet es nichts.

PUT wird auch zum Aktualisieren einer Ressource verwendet

3
sushil pandey

Also, welches sollte man verwenden, um eine Ressource zu erstellen? Oder muss man beides unterstützen?

Sie sollten PATCH verwenden. Sie PATCHEN die Liste der Fragen wie

PATCH /questions HTTP/1.1

mit einer Liste, die Ihr zu erstellendes Objekt enthält wie

[
    {
        "title": "I said semantics!",
        "content": "Is this serious?",
        "answer": "Not really"
    }
]

Es ist eine PATCH-Anfrage als

  • sie ändern die vorhandene Ressourcenliste ohne den gesamten neuen Inhalt bereitzustellen
  • sie ändern den Status Ihrer neuen Frage von nicht existierend in existierend ohne alle Daten anzugeben (der Server wird höchstwahrscheinlich ein id hinzufügen).

Ein großer Vorteil dieser Methode besteht darin, dass Sie mit einer einzigen Anforderung mehrere Entitäten erstellen können, indem Sie sie einfach alle in der Liste angeben.

Dies ist etwas, das PUT offensichtlich nicht kann. Sie können POST zum Erstellen mehrerer Entitäten verwenden, da dies die Küchenspüle von HTTP ist und im Grunde alles kann.

Ein Nachteil ist, dass wahrscheinlich niemand PATCH auf diese Weise verwendet. Ich fürchte, ich habe es gerade erfunden, aber ich hoffe, ich habe eine gute Argumentation geliefert.

Sie könnten stattdessen CREATE verwenden, da benutzerdefinierte HTTP-Verben zulässig sind, funktionieren sie möglicherweise nur mit einigen Tools nicht.

In Bezug auf die Semantik ist CREATE IMHO die einzig richtige Wahl, alles andere ist ein quadratischer Stift in einem runden Loch. Leider haben wir nur runde Löcher.

2
maaartinus

Ich denke, es gibt auch einen interessanten Punkt, der in dieser Frage von PUT vs POST nicht geteilt wurde:

Wenn Sie eine Webanwendung haben möchten, die ohne JavaScript funktioniert (z. B. wenn jemand einen Befehlszeilenbrowser wie Lynx oder ein Browser-Addon wie NoScript oder uMatrix verwendet), müssen Sie POST zum Senden verwenden Daten seit HTML-Formularen unterstützen nur GET- und POST HTTP-Anforderungen.

Wenn Sie die progressive Verbesserung ( https://en.wikipedia.org/wiki/Progressive_enhancement ) verwenden möchten, damit Ihre Webanwendung überall mit und ohne JavaScript funktioniert, können Sie andere HTTP-Methoden wie diese nicht verwenden PUT oder DELETE, die nur in der HTTP-Version 1.1 hinzugefügt wurden.

0
baptx