Gemäß der HTTP / 1.1-Spezifikation:
Das
POST
Verfahren ist nicht auf Anforderung verwendet , dass der Ursprungsserver die Entität in der Anforderung als eine neue untergeordnete der Ressource durch die identifizierten umschlossenen nehmenRequest-URI
in derRequest-Line
Mit anderen Worten, POST
wird zum Erstellen verwendet .
Die
PUT
Methode fordert an, dass die eingeschlossene Entität unter der angegebenen gespeichert wirdRequest-URI
. Wenn sich dasRequest-URI
auf eine bereits vorhandene Ressource bezieht, MUSS die eingeschlossene Entität als modifizierte Version der auf dem Ursprungsserver befindlichen Entität betrachtet werden. Wenn derRequest-URI
nicht auf eine vorhandene Ressource verweist und dieser URI vom anfordernden Benutzeragenten als neue Ressource definiert werden kann, kann der Ursprungsserver die Ressource mit diesem URI erstellen. "
Das heißt, PUT
wird zum Erstellen oder Ersetzen verwendet .
Welches sollte also verwendet werden, um eine Ressource zu erstellen? Oder muss man beides unterstützen?
Antworten:
Insgesamt:
Sowohl PUT als auch POST können zum Erstellen verwendet werden.
Sie müssen fragen: "Wozu führen Sie die Aktion aus?" um zu unterscheiden, was Sie verwenden sollten. Angenommen, Sie entwerfen eine API zum Stellen von Fragen. Wenn Sie POST verwenden möchten, tun Sie dies mit einer Liste von Fragen. Wenn Sie PUT verwenden möchten, würden Sie dies für eine bestimmte Frage tun.
Großartig, beide können verwendet werden, also welches sollte ich in meinem RESTful-Design verwenden:
Sie müssen nicht sowohl PUT als auch POST unterstützen.
Was verwendet wird, bleibt Ihnen überlassen. Denken Sie jedoch daran, das richtige zu verwenden, je nachdem, auf welches Objekt Sie in der Anforderung verweisen.
Einige Überlegungen:
Ein Beispiel:
Ich habe Folgendes als Teil einer anderen Antwort auf SO zu diesem Thema geschrieben :
Zusätzlich und etwas präziser, RFC 7231 Abschnitt 4.3.4 PUT- Zustände (Hervorhebung hinzugefügt),
quelle
Im Internet finden Sie Aussagen, die besagen
Beides ist nicht ganz richtig.
Besser ist es, zwischen PUT und POST zu wählen, basierend auf der Idempotenz 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. Tun Sie es so oft Sie möchten, und das Ergebnis ist das gleiche.
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 untergeordnete Ressource hinzu oder bewirkt eine Änderung. Ein POST ist nicht idempotent, so wie er
x++
nicht idempotent ist.Mit diesem Argument dient PUT zum Erstellen, wenn Sie die URL des zu erstellenden Objekts kennen. POST kann zum Erstellen verwendet werden, wenn Sie die URL der "Fabrik" oder des Managers für die Kategorie der Dinge kennen, die Sie erstellen möchten.
damit:
oder:
quelle
name
unddate
. Wenn wir eine Entität mit einer vorhandenen Entität habenname
unddate
dann Anfragen an sie stellen und nur a angeben,name
besteht das richtige Verhalten von PUT darin,date
die Entität zu löschen , während POST möglicherweise nur die angegebenen Eigenschaften aktualisiert und die nicht spezifizierten Eigenschaften unverändert lässt bevor die Anfrage gestellt wurde. Klingt das richtig / vernünftig oder ist es eine missbräuchliche Verwendung von PUT (ich habe Verweise auf PATCH gesehen , was angemessener erscheint, aber noch nicht existiert)?Die relevante Spezifikation für PUT und POST ist RFC 2616 §9.5ff.
POST erstellt eine untergeordnete Ressource . POST
/items
erstellt also eine Ressource, die unter der/items
Ressource gespeichert ist. Z.B./items/1
. Durch zweimaliges Senden desselben Postpakets 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 verwendetPUT ersetzt die Ressource unter der bekannten URL, falls sie bereits vorhanden ist. Das zweimalige Senden derselben Anforderung hat also keine Auswirkung. Mit anderen Worten, Aufrufe von PUT sind idempotent .
Der RFC lautet wie folgt:
Hinweis: PUT wurde hauptsächlich zum Aktualisieren von Ressourcen verwendet (indem sie vollständig ersetzt wurden). In letzter Zeit gibt es jedoch eine Tendenz zur Verwendung von PATCH zum Aktualisieren vorhandener Ressourcen, da PUT angibt, dass es die gesamte Ressource ersetzt. RFC 5789.
Update 2018 : Es gibt einen Fall, der gemacht werden kann, um PUT zu vermeiden. Siehe "REST ohne PUT"
entnommen aus REST API Design - Ressourcenmodellierung von Prakash Subramaniam von Thoughtworks
Dies zwingt die API, Probleme beim Statusübergang zu vermeiden, wenn mehrere Clients eine einzelne Ressource aktualisieren, und passt besser zu Event Sourcing und CQRS. Wenn die Arbeit asynchron ausgeführt wird, erscheint es angemessen, die Transformation zu POSTEN und darauf zu warten, dass sie angewendet wird.
quelle
Zusammenfassung:
Erstellen:
Kann mit PUT oder POST folgendermaßen durchgeführt werden:
Aktualisieren:
Kann nur mit PUT folgendermaßen durchgeführt werden:
Erläuterung:
Wenn mit REST und URI als allgemeine tun haben , haben Sie generic auf der linken und bestimmten auf der rechten . Die Generika werden normalerweise als Sammlungen bezeichnet, und die spezifischeren Elemente können als Ressource bezeichnet werden . Beachten Sie, dass eine Ressource eine Sammlung enthalten kann .
Wenn Sie POST verwenden, beziehen Sie sich immer auf eine Sammlung . Wenn Sie also sagen:
Sie einen neuen Benutzer die Entsendung Benutzer Sammlung .
Wenn Sie fortfahren und so etwas versuchen:
es wird funktionieren, aber Sie sagen , dass Sie eine Ressource zu dem semantisch hinzufügen möchten john Sammlung unter der Benutzer Sammlung .
Sobald Sie PUT verwenden, verweisen Sie auf eine Ressource oder ein einzelnes Element, möglicherweise innerhalb einer Sammlung . Also wenn du sagst:
Sie sind mit dem Server - Update zu sagen, oder erstellen , wenn es das nicht existiert, john Ressource unter dem Benutzer Sammlung .
Spezifikation:
Lassen Sie mich einige wichtige Teile der Spezifikation hervorheben:
POST
Erstellt daher eine neue Ressource für eine Sammlung .
STELLEN
Erstellen oder aktualisieren Sie daher basierend auf dem Vorhandensein der Ressource .
Referenz:
quelle
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".POST
Wenn Sie auf example.com/users gehen, da SieURL
den Benutzer noch nicht kennen , möchten Sie, dass der Server ihn erstellt.Sie gehen
PUT
zu example.com/users/id, da Sie einen bestimmten Benutzer ersetzen / erstellen möchten .Wenn Sie zweimal mit denselben Daten posten, werden zwei identische Benutzer mit unterschiedlichen IDs erstellt. Durch zweimaliges PUT mit denselben Daten wird der Benutzer zum ersten Mal erstellt und beim zweiten Mal auf den gleichen Status aktualisiert (keine Änderungen). Da Sie nach einer
PUT
beliebigen Anzahl von Spielen denselben Zustand haben, wird er jedes Mal als "gleich stark" bezeichnet - idempotent. Dies ist nützlich, um Anforderungen automatisch erneut zu versuchen. Nicht mehr "Sind Sie sicher, dass Sie erneut senden möchten", wenn Sie die Zurück-Taste im Browser drücken.Ein allgemeiner Rat ist,
POST
wenn der Server die Kontrolle über dieURL
Generierung Ihrer Ressourcen haben soll. Verwenden SiePUT
sonst. Lieber lieberPUT
alsPOST
.quelle
user 5
wenn er noch nicht vorhanden ist? Meinst du nichtupdate, replace if already exists
? oder soPUT
Kann auch verwendet werden, um den Wert einer vorhandenen Ressource in ihrer Gesamtheit zu ersetzen .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 funktioniert nicht so gut, wenn Sie beispielsweise eine datenbankgenerierte ID benötigen, die zurückgegeben werden muss, damit Sie zukünftige Suchvorgänge oder Aktualisierungen durchführen können.
Also: So speichern Sie einen vorhandenen Benutzer oder einen, bei dem der Client die ID generiert und überprüft wurde, ob die ID eindeutig ist:
Verwenden Sie andernfalls POST, um das Objekt zunächst zu erstellen, und PUT, um das Objekt zu aktualisieren:
quelle
POST /users
. (Beachten Sie, dass dies/users
Plural ist.) Dies hat zur Folge, dass ein neuer Benutzer erstellt und zu einer untergeordneten Ressource der/users
Sammlung gemacht wird.GET /users
macht Sinn, es liest sich wie Sie wollen, aber ich würde mitGET /user/<id>
oderPOST /user
(mit Nutzlast für den neuen Benutzer) einverstanden sein, weil es richtig lautet: "Hol mir Benutzer 5" ist seltsam, aber "Hol mir Benutzer 5" ist natürlicher. Ich würde wahrscheinlich immer noch auf die Seite der Pluralisierung fallen :)Verwenden Sie POST zum Erstellen und PUT zum Aktualisieren. So macht es Ruby on Rails jedenfalls.
quelle
POST /items
Fügt einer bereits definierten Ressource ein neues Element hinzu ('Element'). Es heißt nicht, wie die Antwort sagt, "eine Gruppe erstellen". Ich verstehe nicht, warum dies 12 Stimmen hat.PUT /items/42
auch für das Erstellen einer Ressource gilt, jedoch nur, wenn der Client das Recht hat, die Ressource zu benennen . (Erlaubt Rails einem Client diesesBeide werden für die Datenübertragung zwischen Client und Server verwendet, es gibt jedoch subtile Unterschiede zwischen ihnen:
Analogie:
Social Media / Netzwerk-Analogie:
quelle
REST ist ein sehr hochrangiges Konzept. Tatsächlich wird HTTP überhaupt nicht erwähnt!
Wenn Sie Zweifel an der Implementierung von REST in HTTP haben, können Sie sich jederzeit die AtomPub- Spezifikation (Atom Publication Protocol) ansehen . AtomPub ist ein Standard zum Schreiben von RESTful-Webservices mit HTTP, der von vielen HTTP- und REST-Leuchten entwickelt wurde. Einige Beiträge stammen von Roy Fielding, dem Erfinder von REST und (Mit-) Erfinder von HTTP.
Möglicherweise können Sie AtomPub sogar direkt verwenden. Obwohl es aus der Blogging-Community stammt, ist es in keiner Weise auf das Bloggen beschränkt: Es ist ein generisches Protokoll für die REST-fähige Interaktion mit beliebigen (verschachtelten) Sammlungen beliebiger Ressourcen über HTTP. Wenn Sie Ihre Anwendung als verschachtelte Sammlung von Ressourcen darstellen können, können Sie einfach AtomPub verwenden und müssen sich keine Gedanken darüber machen, ob Sie PUT oder POST verwenden, welche HTTP-Statuscodes zurückgegeben werden sollen und all diese Details.
Dies ist, was AtomPub zur Ressourcenerstellung zu sagen hat (Abschnitt 9.2):
quelle
Die Entscheidung, ob PUT oder POST zum Erstellen einer Ressource auf einem Server mit einer HTTP + REST-API verwendet werden soll, hängt davon ab, wem die URL-Struktur gehört. Wenn der Client die URL-Struktur kennt oder an deren Definition beteiligt ist, ist dies eine unnötige Kopplung, ähnlich den unerwünschten Kopplungen, die durch SOA entstanden sind. Das Entweichen von Kupplungstypen ist der Grund, warum REST so beliebt ist. Daher ist POST die richtige Methode. Es gibt Ausnahmen von dieser Regel, die auftreten, wenn der Client die Kontrolle über die Standortstruktur der von ihm bereitgestellten Ressourcen behalten möchte. Dies ist selten und bedeutet wahrscheinlich, dass etwas anderes nicht stimmt.
An dieser Stelle werden einige Leute argumentieren, dass der Client die URL der Ressource kennt , wenn RESTful-URLs verwendet werden, und daher ein PUT akzeptabel ist. Aus diesem Grund sind kanonische, normalisierte, Ruby on Rails- und 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 Folgendes feststellt :
Die Idee einer RESTful-URL stellt tatsächlich eine Verletzung von REST dar, da der Server für die URL-Struktur verantwortlich ist und frei entscheiden sollte, wie sie verwendet werden soll, 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 Entwurfsüberlegung verbunden, da POST nicht idempotent ist. Dies bedeutet, dass das mehrmalige Wiederholen eines POST nicht jedes Mal das gleiche Verhalten garantiert. Dies macht den Leuten Angst, PUT zu verwenden, um Ressourcen zu erstellen, wenn sie dies nicht sollten. Sie wissen, dass es falsch ist (POST ist für CREATE), aber sie tun es trotzdem, weil sie nicht wissen, wie sie dieses Problem lösen sollen. Diese Besorgnis zeigt sich in der folgenden Situation:
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:
Die Antwort mit dem Statuscode 409 Conflict ist der richtige Rückgriff, weil :
Update basierend auf der Version von RFC 7231 zum Ersetzen von 2616
RFC 7231 ersetzt 2616 und beschreibt in Abschnitt 4.3.3 die folgende mögliche Antwort für einen POST
Es kann jetzt verlockend sein, einfach einen 303 zurückzugeben, falls ein POST wiederholt wird. Das Gegenteil ist jedoch der Fall. Die Rückgabe eines 303 wäre nur dann sinnvoll, wenn mehrere Erstellungsanforderungen (unterschiedliche Ressourcen erstellen) denselben Inhalt zurückgeben. Ein Beispiel wäre ein "Danke, dass Sie Ihre Anforderungsnachricht gesendet haben", das 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 sollte.
Weitere Informationen hierzu finden Sie in diesem Artikel .
quelle
Ich mag diesen Rat aus der Definition von PUT in RFC 2616 :
Dies stimmt mit dem anderen Rat überein, dass PUT am besten auf Ressourcen angewendet wird, die bereits einen Namen haben, und POST ist gut geeignet, um ein neues Objekt unter einer vorhandenen Ressource zu erstellen (und den Server benennen zu lassen).
Ich interpretiere dies und die Idempotenzanforderungen an PUT so, dass:
quelle
Zusamenfassend:
PUT ist idempotent, wobei der Ressourcenzustand derselbe ist, wenn dieselbe Operation einmal oder mehrmals ausgeführt wird.
POST ist nicht idempotent, wobei der Ressourcenzustand möglicherweise anders wird, wenn die Operation im Vergleich zur einmaligen Ausführung mehrmals ausgeführt wird.
Analogie zur Datenbankabfrage
PUT Sie können sich ähnlich wie "UPDATE STUDENT SET address =" abc "vorstellen, wobei id =" 123 ";
POST Sie können sich so etwas wie "INSERT IN STUDENT (Name, Adresse) VALUES (" abc "," xyzzz ") vorstellen;
Die Studenten-ID wird automatisch generiert.
Wenn bei PUT dieselbe Abfrage mehrmals oder einmal ausgeführt wird, bleibt der Status der STUDENT-Tabelle derselbe.
Wenn bei POST dieselbe Abfrage mehrmals ausgeführt wird, werden mehrere Student-Datensätze in der Datenbank erstellt, und der Datenbankstatus ändert sich bei jeder Ausführung einer "INSERT" -Abfrage.
HINWEIS: PUT benötigt einen Ressourcenspeicherort (bereits eine Ressource), an dem eine Aktualisierung durchgeführt werden 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 erforderlich ist.
Einige können sich vorstellen, dass Aktualisierungen mit POST durchgeführt werden können. Es gibt keine feste Regel, welche für Updates oder welche für die Erstellung verwendet werden soll. Auch dies sind Konventionen, und ich neige intuitiv zu den oben genannten Überlegungen und folge ihnen.
quelle
POST ist wie das Versenden eines Briefes an eine Mailbox oder das Versenden einer E-Mail an eine E-Mail-Warteschlange. PUT ist wie wenn Sie ein Objekt in ein Ablagefach oder einen Platz in einem Regal legen (es hat eine bekannte Adresse).
Mit POST veröffentlichen Sie an die Adresse der QUEUE oder COLLECTION. Mit PUT setzen Sie an die Adresse des ITEM.
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.
quelle
Neue Antwort (jetzt, wo ich REST besser verstehe):
PUT ist lediglich eine Aussage darüber, welchen Inhalt der Dienst von nun an verwenden soll, um Darstellungen der vom Client identifizierten Ressource zu rendern. POST ist eine Aussage darüber, welchen Inhalt der Dienst von nun an enthalten soll (möglicherweise dupliziert), aber es ist Sache des Servers, diesen Inhalt zu identifizieren.
PUT x
(wennx
eine Ressource identifiziert wird ): "Ersetzen Sie den Inhalt der durch identifizierten Ressource durchx
meinen Inhalt."PUT x
(wennx
keine Ressource identifiziert wird): "Erstellen Sie eine neue Ressource, die meinen Inhalt enthält, und verwenden Sie siex
, 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 derx
identifizierenden identisch oder untergeordnet sein ." „ Y ‚s Ressource untergeordnet ist x ‘s Ressource“ ist typischerweise aber notwendigerweise , indem sie nicht implementiert y einen Subpfad von x (beispielsweise x =/foo
und y =/foo/bar
) und Modifizieren der Darstellung (e) von x ‚s - Ressource , die Existenz widerzuspiegeln einer neuen Ressource, zB mit einem Hyperlink zu yRessource und einige Metadaten. Nur letzteres ist für ein gutes Design wirklich wichtig, da URLs in REST undurchsichtig sind. Sie sollten Hypermedia anstelle der clientseitigen URL-Konstruktion verwenden, um den Service trotzdem zu durchlaufen.In REST gibt es keine Ressource, die "Inhalt" enthält. Ich beziehe mich als "Inhalt" auf Daten, die der Dienst verwendet, um Darstellungen konsistent zu rendern. Es besteht normalerweise aus einigen verwandten Zeilen in einer Datenbank oder einer Datei (z. B. einer Bilddatei). Es ist Sache des Dienstes, den Inhalt des Benutzers in etwas zu konvertieren, das der Dienst verwenden kann, z. B. das Konvertieren einer JSON-Nutzlast in SQL-Anweisungen.
Ursprüngliche Antwort (möglicherweise leichter zu lesen) :
PUT /something
(falls/something
bereits vorhanden): "Nimm, was du hast/something
und ersetze es durch das, was ich dir gebe."PUT /something
(falls/something
noch nicht vorhanden): "Nimm was ich dir gebe und lege es an/something
."POST /something
: "Nehmen Sie, was ich Ihnen gebe, und platzieren Sie es an einer beliebigen Stelle,/something
solange Sie mir die URL geben, wenn Sie fertig sind."quelle
Kurze Antwort:
Einfache Faustregel: Verwenden Sie POST zum Erstellen und PUT zum Aktualisieren.
Lange Antwort:
POST:
STELLEN:
Längere Antwort:
Um es zu verstehen, müssen wir uns fragen, warum PUT erforderlich war und welche Probleme PUT zu lösen versuchte, die POST nicht lösen konnte.
Aus Sicht einer REST-Architektur ist nichts von Bedeutung. Wir hätten auch ohne PUT leben können. Aus Sicht eines Kundenentwicklers hat dies sein Leben jedoch viel einfacher gemacht.
Vor dem PUT konnten Clients die vom Server generierte URL nicht direkt kennen oder ob alle von ihm generierten URLs vorhanden waren oder ob die an den Server zu sendenden Daten bereits aktualisiert wurden oder nicht. PUT entlastete den Entwickler von all diesen Kopfschmerzen. PUT ist idempotent, PUT behandelt die Rennbedingungen und PUT lässt den Client die URL auswählen.
quelle
Ruby on Rails 4.0 verwendet die 'PATCH'-Methode anstelle von PUT, um Teilaktualisierungen durchzuführen.
RFC 5789 sagt über PATCH (seit 1995):
" Edge Rails: PATCH ist die neue primäre HTTP-Methode für Updates ", erklärt es.
quelle
Auf die Gefahr hin, das bereits Gesagte erneut zu wiederholen, scheint es wichtig zu sein, sich daran zu erinnern, dass PUT impliziert, dass der Client beim Erstellen einer Ressource kontrolliert, wie die URL letztendlich aussehen wird . Bei der Wahl zwischen PUT und POST geht es also darum, wie sehr Sie dem Client vertrauen können, dass er die richtige, normalisierte URL bereitstellt, die mit Ihrem URL-Schema übereinstimmt.
Wenn Sie dem Client nicht vollständig vertrauen können, dass er das Richtige tut, ist es besser, POST zu verwenden, um ein neues Element zu erstellen und die URL in der Antwort an den Client zurückzusenden.
quelle
Location
Header zurückgibt , der den Namen der kanonischen Ressource enthält.PUT /X-files/series/4/episodes/max
), und der Server antwortet mit einem URI, der einen kurzen kanonischen eindeutigen Link zu dieser neuen Ressource (dh/X-Ffiles/episodes/91
)Auf sehr einfache Weise nehme ich das Beispiel der Facebook-Timeline.
Fall 1: Wenn Sie etwas auf Ihrer Timeline veröffentlichen, ist es ein neuer Eintrag. In diesem Fall verwenden sie die POST-Methode, da die POST-Methode 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 der Datenbank hinzuzufügen, und PUT , um etwas in der Datenbank zu aktualisieren .
quelle
Die wichtigste Überlegung ist die Zuverlässigkeit . Wenn eine POST-Nachricht 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 zufällig 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:
quelle
Leser, die neu in diesem Thema sind, werden von der endlosen Diskussion darüber, was Sie tun sollten , und dem relativen Fehlen von Lehren aus der Erfahrung beeindruckt sein. Die Tatsache, dass REST gegenüber SOAP "bevorzugt" wird, ist vermutlich ein Lernen auf hohem Niveau aus Erfahrung, aber meine Güte, wir müssen von dort aus Fortschritte gemacht haben? Es ist 2016. Roys Dissertation war im Jahr 2000. Was haben wir entwickelt? Hat es Spaß gemacht? War es einfach zu integrieren? Zu unterstützen? Wird es den Aufstieg von Smartphones und flockigen Mobilfunkverbindungen bewältigen?
Laut ME sind reale Netzwerke unzuverlässig. Fordert eine Zeitüberschreitung an. 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 ihrem Weg ins Wasser fallen, oder die Antwort kann auf dem Rückweg ins Wasser fallen. Unter diesen Umständen war es für mich immer etwas brutal und naiv, PUT-, POST- und DELETE-Anfragen direkt gegen materielle Ressourcen zu stellen.
HTTP unternimmt nichts, um einen zuverlässigen Abschluss der Anforderungsantwort sicherzustellen, und das ist in Ordnung, da dies die Aufgabe netzwerkfähiger Anwendungen ist. Wenn Sie eine solche Anwendung entwickeln, können Sie durch die Rahmen springen, um PUT anstelle von POST zu verwenden, und dann durch weitere Rahmen, um eine bestimmte Art von Fehler auf dem Server zu melden, wenn Sie doppelte Anforderungen erkennen. Zurück auf dem 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 an die Ressource an. POST wird nur dafür verwendet. Sobald der Client sicher im Besitz des URI der frisch geprägten Aktion ist, sendet er die unsichere Anforderung an den Aktions-URI und nicht an die Zielressource . Das Auflösen der Aktion und das Aktualisieren der "echten" Ressource ist ordnungsgemäß Aufgabe Ihrer API und hier vom unzuverlässigen Netzwerk entkoppelt.
Der Server erledigt das Geschäft, gibt die Antwort zurück und speichert sie anhand des vereinbarten Aktions-URI . Wenn etwas schief geht, wiederholt der Client die Anforderung (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 den Platzhalter für das Ergebnis und geben ihn zurück, bevor wir etwas unternehmen. Ebenso wie ein Versprechen kann eine Aktion einmal erfolgreich sein oder fehlschlagen, aber das Ergebnis kann wiederholt abgerufen werden.
Das Beste ist, dass wir sendenden und empfangenden Anwendungen die Möglichkeit geben, die eindeutig identifizierte Aktion mit der Eindeutigkeit in ihrer jeweiligen Umgebung zu verknüpfen. Und wir können anfangen, verantwortungsbewusstes Verhalten von Kunden zu fordern und durchzusetzen: Wiederholen Sie Ihre Anfragen so oft Sie möchten, aber generieren Sie keine neue Aktion, bis Sie über ein endgültiges Ergebnis der vorhandenen verfügen.
Als solche verschwinden zahlreiche heikle Probleme. Wiederholte Einfügeanforderungen erzeugen keine Duplikate, und wir erstellen die eigentliche Ressource erst, wenn wir im Besitz der Daten sind. (Datenbankspalten können nicht nullwertfähig bleiben). Wiederholte Aktualisierungsanforderungen treffen nicht auf inkompatible Zustände und überschreiben nachfolgende Änderungen nicht. Clients können die ursprüngliche Bestätigung aus irgendeinem Grund (erneut) abrufen und nahtlos verarbeiten (Client stürzte ab, Antwort ging verloren 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 das endgültige Ergebnis überprüfen kann. Der schönste Teil dieses Musters ist seine Kung-Fu (Panda) -Eigenschaft. Wir nehmen eine Schwäche, die Neigung der Kunden, eine Anfrage zu wiederholen, wenn sie die Antwort nicht verstehen, und verwandeln sie in eine Stärke :-)
Bevor Sie mir sagen, dass dies nicht RESTful ist, bedenken Sie bitte die zahlreichen Möglichkeiten, wie REST-Prinzipien respektiert werden. Clients erstellen keine URLs. Die API bleibt erkennbar, 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 endgültig zu antworten. Selbst wenn Sie Aktionen nur eine Woche lang speichern, haben Kunden reichlich Gelegenheit, sich zu informieren. Wenn Sie sehr große Volumes haben, möchten Sie möglicherweise einen dedizierten säurekonformen Schlüsselwertspeicher oder eine In-Memory-Lösung.
quelle
Zusätzlich zu den von anderen vorgeschlagenen Unterschieden möchte ich noch einen hinzufügen.
In der POST- Methode können Sie Body-Parameter senden
form-data
Bei der PUT- Methode müssen Sie Body-Parameter einsenden
x-www-form-urlencoded
Header
Content-Type:application/x-www-form-urlencoded
Demnach können Sie in der PUT- Methode keine Dateien oder mehrteiligen Daten senden
BEARBEITEN
Was bedeutet, wenn Sie einreichen müssen
Sie sollten die POST- Methode verwenden
quelle
Es scheint immer eine gewisse Verwirrung darüber zu bestehen, wann der HTTP-POST im Vergleich zur HTTP-PUT-Methode für REST-Services 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:
Es ist wahr, dass das R (etrieve) und D (elete) der CRUD-Operationen direkt auf die HTTP-Methoden GET bzw. DELETE abgebildet 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 POST-Methode ist nicht idempotent. Das heißt, eine Operation ist idempotent, wenn sie ein- oder mehrmals an einer Ressource ausgeführt werden kann und immer den gleichen Status dieser Ressource zurückgibt. Während eine nicht idempotente Operation einen geänderten Status 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 gehe ich davon aus, dass ich die HTTP-PUT-Methode im Vergleich zur HTTP-POST-Methode für REST-Services verwende: Verwenden Sie die HTTP-PUT-Methode, wenn:
In beiden Fällen können diese Vorgänge mehrmals mit denselben Ergebnissen ausgeführt werden. Das heißt, die Ressource wird nicht geändert, wenn die Operation mehr als einmal angefordert wird. Daher eine echte idempotente Operation. Verwenden Sie die HTTP-POST-Methode, wenn:
Fazit
Korrelieren Sie CRUD-Operationen nicht direkt und ordnen Sie sie HTTP-Methoden für REST-Services 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 HTTP-POST-Methode.
quelle
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 perfekt genug. Es ist also eine Designentscheidung.
Wie in Ihrem Zitat erwähnt, verwenden Sie PUT zum Erstellen, da einer IRI keine Ressource zugewiesen ist, und Sie möchten trotzdem eine Ressource erstellen. Beispielsweise wird
PUT /users/123/password
normalerweise das alte Kennwort durch ein neues ersetzt. Sie können es jedoch verwenden, um ein Kennwort zu erstellen, falls es noch nicht vorhanden ist (z. B. durch frisch registrierte Benutzer oder durch Wiederherstellen gesperrter Benutzer).quelle
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 "außerhalb des Bandes" definiert wird. Wenn die Nachricht als Hinzufügen einer Ressource zu einem Verzeichnis interpretiert werden kann, wäre 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 und GET und DELETE auf eine Ressource beziehen, sind sie per Definition auch idempotent.
POST kann die anderen drei Funktionen ausführen, aber dann geht die Semantik der Anforderung auf den Vermittlern 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 angewendet wird (dies kann jedoch möglich sein).
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 - es kann die Ressource erstellen, aber keine Updates zulassen. Das einzige, was für PUT erforderlich ist, ist, dass es auf eine bestimmte Ressource verweist und seine Nutzlast die Darstellung dieser Ressource ist. Ein erfolgreicher PUT bedeutet (abgesehen 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 zweiten 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 Ressource) wäre, eine Ressource unter Verwendung der in dieser Nachricht definierten Werte zu erstellen.
quelle
Die Semantik soll insofern unterschiedlich sein, als "PUT" wie "GET" idempotent sein soll - das heißt, Sie können dieselbe exakte PUT-Anforderung mehrmals ausführen und das Ergebnis ist so, als hätten Sie sie nur einmal ausgeführt.
Ich werde die Konventionen beschreiben, die meiner Meinung nach am weitesten verbreitet und am nützlichsten sind:
Wenn Sie eine Ressource an eine bestimmte URL setzen, geschieht dies unter dieser URL oder in einer ähnlichen Richtung.
Wenn Sie an eine Ressource unter einer bestimmten URL posten, veröffentlichen Sie häufig eine verwandte Information an diese 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 einer URL hinzufügen. Wenn Sie jedoch eine Nachricht an einen vorhandenen Stream senden möchten, senden Sie sie an die URL.
Das Ändern der Eigenschaften des Streams kann entweder mit PUT oder POST erfolgen. Verwenden Sie "PUT" grundsätzlich nur, 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.
quelle
Meistens werden Sie sie folgendermaßen verwenden:
Zum Beispiel:
In beiden Fällen enthält der Anforderungshauptteil die Daten für die Ressource, die erstellt oder aktualisiert werden soll. Aus den Routennamen sollte ersichtlich sein, dass POST nicht idempotent ist (wenn Sie es dreimal aufrufen, werden 3 Objekte erstellt), aber PUT ist idempotent (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 jederzeit einen 404-Fehler zurückgeben, wenn Sie ihn nur zum Ändern verwenden möchten.
Beachten Sie, dass POST ein neues Element in der Sammlung "erstellt" und PUT ein Element unter einer bestimmten URL "ersetzt". Es ist jedoch sehr üblich, PUT für teilweise Änderungen zu verwenden, dh nur zum Aktualisieren vorhandener Ressourcen und zu verwenden Ändern Sie nur die im Text enthaltenen Felder (ignorieren Sie die anderen Felder). Dies ist technisch nicht korrekt. Wenn Sie REST-Purist sein möchten, sollte PUT die gesamte Ressource ersetzen und PATCH für die teilweise Aktualisierung verwenden. Es ist mir persönlich egal, wie klar und konsistent das Verhalten auf allen API-Endpunkten ist.
Denken Sie daran, REST ist eine Reihe von Konventionen und Richtlinien, um Ihre API einfach zu halten. Wenn Sie am Ende eine komplizierte Problemumgehung haben, nur um das Kontrollkästchen "RESTfull" zu aktivieren, haben Sie den Zweck verfehlt;)
quelle
Während es wahrscheinlich eine agnostische Art gibt, diese zu beschreiben, scheint es im Widerspruch zu verschiedenen Aussagen von Antworten auf Websites zu stehen.
Lassen Sie uns hier sehr klar und direkt sein. Wenn Sie ein .NET-Entwickler sind, der mit der Web-API arbeitet, finden Sie die Fakten (aus der Microsoft API-Dokumentation) unter http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web -api-das-unterstützt-grobe-Operationen :
Sicher, Sie können "POST" zum Aktualisieren "verwenden", aber befolgen Sie einfach die für Sie festgelegten Konventionen mit Ihrem vorgegebenen Framework. In meinem Fall handelt es sich um eine .NET / Web-API, daher ist PUT für UPDATE keine Debatte.
Ich hoffe, dies hilft allen Microsoft-Entwicklern, die alle Kommentare mit Links zu Amazon- und Sun / Java-Websites lesen.
quelle
Hier ist eine einfache Regel:
STELLEN to a URL sollte verwendet werden, um die Ressource zu aktualisieren oder zu erstellen, die sich unter dieser URL befindet.
POST an eine URL sollte verwendet werden, um eine Ressource zu aktualisieren oder zu erstellen, die sich an einer anderen ("untergeordneten") URL befindet oder nicht über HTTP gefunden werden kann.
quelle
Wenn Sie mit Datenbankoperationen vertraut sind, gibt es
Ich verwende
PUT
zum Zusammenführen und Aktualisieren ähnliche Vorgänge undPOST
zum Einfügen.quelle
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 Best Practices beim Entwerfen einer RESTful-API sind. Die HTTP-Spezifikation als solche beschränkt die Verwendung von PUT / POST nicht mit einigen Einschränkungen für das Erstellen / Aktualisieren von Ressourcen. Schauen Sie sich http://techoctave.com/c7/posts/71-twitter-rest-api-dissected an , in dem die Best Practices zusammengefasst sind.
quelle