Leser, die neu in diesem Thema sind, werden von der endlosen Diskussion darüber, was Sie tun sollten, und dem relativen Mangel an Erfahrungen beeindruckt sein. Die Tatsache, dass REST "bevorzugt" wird gegenüber SOAP, ist, nehme ich an, ein Lernen auf hoher Ebene aus Erfahrungen, aber Gut, wir müssen von dort aus vorangekommen sein, oder? Es ist 2016. Roys Dissertation war im Jahr 2000. Was haben wir entwickelt? War es lustig? War es einfach zu integrieren? Zu unterstützen? Wird es den Anstieg von Smartphones und instabilen mobilen Verbindungen bewältigen?
Nach ME sind die realen Netzwerke unzuverlässig. Anfragen laufen ab. Verbindungen werden zurückgesetzt. Netzwerke fallen stunden- oder tagelang aus. Züge fahren in Tunnel mit mobilen Benutzern an Bord. Für eine beliebige Anfrage (wie gelegentlich in all diesen Diskussionen anerkannt) kann die Anfrage auf ihrem Weg ins Wasser fallen oder die Antwort kann auf ihrem Rückweg ins Wasser fallen. Unter diesen Bedingungen erscheinen mir das direkte Ausgeben von PUT-, POST- und DELETE-Anfragen gegen substantielle Ressourcen immer ein wenig brutal und naiv.
HTTP tut nichts, um die zuverlässige Beendigung der Anfrage-Antwort zu gewährleisten, und das ist in Ordnung, denn das ist eigentlich die Aufgabe von netzwerkbezogenen Anwendungen. Bei der Entwicklung einer solchen Anwendung können Sie sich durch Reifen springen, um PUT anstelle von POST zu verwenden, dann durch weitere Reifen, um auf dem Server eine bestimmte Art von Fehler zu geben, wenn Sie doppelte Anfragen feststellen. Zurück beim Client müssen Sie dann durch Reifen springen, um diese Fehler zu interpretieren, neu abzurufen, neu zu validieren und erneut zu senden.
Oder Sie können dies tun: Betrachten Sie Ihre unsicheren Anfragen als ephemere Einzelbenutzer-Ressourcen (nennen wir sie Aktionen). Clients fordern eine neue "Aktion" auf einer substantiellen Ressource mit einem leeren POST auf die Ressource an. POST wird nur hierfür verwendet. Sobald der Client im Besitz des URIs der frisch erstellten Aktion ist, PUT der Client die unsichere Anfrage auf den Aktions-URI, nicht auf die Zielressource. Das Bearbeiten der Aktion und Aktualisieren der "echten" Ressource ist die eigentliche Aufgabe Ihrer API und hier von dem unzuverlässigen Netzwerk entkoppelt.
Der Server erledigt das Geschäft, liefert die Antwort zurück und speichert sie am vereinbarten Aktions-URI ab. Wenn etwas schiefgeht, wiederholt der Client die Anfrage (natürliches Verhalten!), und wenn der Server sie bereits gesehen hat, wiederholt er die gespeicherte Antwort und tut nichts weiteres.
Sie werden schnell die Ähnlichkeit mit Versprechen erkennen: Wir erstellen und geben den Platzhalter für das Ergebnis zurück, bevor wir irgendetwas tun. Wie bei einem Versprechen kann eine Aktion einmal erfolgreich oder erfolglos sein, aber ihr Ergebnis kann wiederholt abgerufen werden.
Am besten geben wir den sendenden und empfangenden Anwendungen die Möglichkeit, die eindeutig identifizierte Aktion mit der Einzigartigkeit in ihren jeweiligen Umgebungen zu verknüpfen. Und wir können anfangen, verantwortungsvolles Verhalten von Clients zu verlangen und durchzusetzen: Wiederholen Sie Ihre Anfragen so oft Sie möchten, aber generieren Sie keine neue Aktion, bis Sie im Besitz eines definitiven Ergebnisses von der vorhandenen sind.
Auf diese Weise verschwinden zahlreiche knifflige Probleme. Wiederholte Einfügeanforderungen erzeugen keine Duplikate, und wir erstellen die echte Ressource nicht, bis wir im Besitz der Daten sind (Datenbankspalten können nicht-nulle bleiben). Wiederholte Update-Anforderungen führen nicht zu inkonsistenten Zuständen und überschreiben keine nachfolgenden Änderungen. Clients können die ursprünglichen Bestätigungen (zum Beispiel bei einem Absturz des Clients, wenn die Antwort verloren gegangen ist usw.) (wieder) abrufen und nahtlos verarbeiten.
Folgende Lösch-Anfragen können die ursprüngliche Bestätigung sehen und verarbeiten, ohne einen 404-Fehler zu erzeugen. Wenn die Dinge länger als erwartet dauern, können wir vorläufig antworten, und wir haben einen Ort, an dem der Client für das endgültige Ergebnis nachsehen kann. Das Schönste an diesem Muster ist seine Kung-Fu (Panda)-Eigenschaft. Wir nehmen eine Schwäche, die Neigung von Clients, eine Anfrage zu wiederholen, wenn sie die Antwort nicht verstehen, und machen sie zu einer Stärke :-)
Bevor Sie mir sagen, dass dies nicht RESTful ist, überlegen Sie bitte die zahlreichen Möglichkeiten, in denen REST-Prinzipien respektiert werden. Clients konstruieren keine URLs. Die API bleibt auffindbar, wenn auch mit einer kleinen Änderung der Semantik. HTTP-Verben werden angemessen verwendet. Wenn Sie denken, dass dies eine große Änderung in seiner Umsetzung ist, kann ich Ihnen aus Erfahrung sagen, dass es nicht so ist.
Wenn Sie denken, dass Sie enorme Datenmengen speichern müssen, lassen Sie uns über Volumina sprechen: Eine typische Update-Bestätigung ist nur ein Bruchteil eines Kilobyte. HTTP gibt Ihnen derzeit eine Minute oder zwei Zeit, um endgültig zu antworten. Selbst wenn Sie Aktionen nur für eine Woche speichern, haben Clients ausreichend Gelegenheit, aufzuholen. Wenn Sie sehr hohe Volumina haben, möchten Sie möglicherweise ein dediziertes acid-konformes Schlüssel-Wert-Speicher oder eine In-Memory-Lösung.
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.
7 Stimmen
Leider sind die ersten Antworten zu POST falsch. Überprüfen Sie meine Antwort für eine bessere Erklärung der Unterschiede: stackoverflow.com/a/18243587/2458234
35 Stimmen
PUT und POST sind beide unsichere Methoden. PUT ist jedoch idempotent, während POST es nicht ist. - Weitere Informationen finden Sie unter: restcookbook.com/HTTP%20Methods/put-vs-post/…
4 Stimmen
Du weißt... mir ist klar, dass die Spezifikation PUT als 'aktualisieren' bezeichnet, aber ich denke, jeder wäre viel weniger verwirrt, wenn wir es 'ersetzen' nennen würden, das ist schließlich, was es tut.
3 Stimmen
Im Prinzip funktioniert POST gut für das Erstellen von Ressourcen. Die URL der neu erstellten Ressource sollte im Location-Antwortheader zurückgegeben werden. PUT sollte verwendet werden, um eine Ressource vollständig zu aktualisieren. Bitte verstehen Sie, dass dies die bewährten Methoden beim Entwerfen einer RESTful-API sind. Die HTTP-Spezifikation als solche schränkt die Verwendung von PUT/POST für das Erstellen/Aktualisieren von Ressourcen nicht ein paar Einschränkungen ein. Werfen Sie einen Blick auf techoctave.com/c7/posts/71-twitter-rest-api-dissected, das die bewährten Methoden zusammenfasst.
3 Stimmen
Idempotenz
ist der Schlüssel. Lesen Sie PUT oder POST: Die REST-Geschichte von John Calcote. Wenn Ihre Methode idempotent ist, verwenden Sie PUT. Andernfalls verwenden Sie POST.2 Stimmen
Ich verstehe den vorherrschenden Konsens dazu nicht. Die Zitierung des OP für PUT beginnt mit "Die PUT-Methode fordert, dass die enthaltene Entität gespeichert wird....". Das sagt mir "Erstellung". Wenn wir über "etwas hinzufügen" sprechen, sprechen wir von einem Ort, an dem es zuvor nicht war. Du "fuegst" etwas nicht hinzu, um es zu ändern. Wenn Sie ein Dokument ändern, fügen Sie nicht ein neues hinzu. Die Verwendung des HTTP-Verbs PUT um "aktualisieren" zu bedeuten, ist eine schlechte semantische Anpassung.
1 Stimmen
PUT begann als Möglichkeit für frühe Microsoft HTML-Designwerkzeuge, Inhalte direkt auf einen Server zu veröffentlichen. Die Tatsache, dass es auch zum Aktualisieren (im Großen und Ganzen) verwendet wurde, war auf das Fehlen einer anderen Aktualisierungsmethode zurückzuführen. Auch wenn es sich um ein Großhandels-Update handelte, war es wirklich eine Erstellung, nur eine, die idempotent war. Ein "Update" impliziert, dass ein Aspekt des vorherigen Zustands beibehalten wurde.
1 Stimmen
Echtes Szenario in der Elasticsearch-Dokumentation: elastic.co/guide/en/elasticsearch/reference/current/…. Werfen Sie einen Blick auf den Unterschied zwischen allen PUT-Anfragen und dem letzten POST-Anfragebeispiel.
0 Stimmen
Das
JavaBrains
erklärt es sehr klar. Schau dir youtube.com/watch?v=rhTkRK53XdQ an.0 Stimmen
Die Unterschied zwischen den Methoden POST vs PUT sollte im definierten Kontext beschrieben werden. Zum Beispiel hier, die Frage dreht sich um REST und dreht sich tatsächlich um Konsistenz und eine einheitliche Schnittstelle. Solange du die Konsistenz im API-Design respektierst, bist du auf dem richtigen Weg.
0 Stimmen
Beachten Sie, dass wenn Sie möchten, dass eine Webanwendung auch funktioniert, wenn JavaScript deaktiviert ist, sollten Sie POST verwenden: stackoverflow.com/questions/630453/put-vs-post-in-rest/…
0 Stimmen
Die zitierte Aussage des OP über POST ist nicht mehr gültig. "Die tatsächliche Funktion, die von der POST-Methode ausgeführt wird, wird vom Server bestimmt und hängt normalerweise vom effektiven Anfrageresource-Identifikator (URI) ab. Die Aktion, die von der POST-Methode ausgeführt wird, führt möglicherweise nicht zu einer Ressource, die mit einem URI identifiziert werden kann." über tools.ietf.org/html/…
0 Stimmen
Die Idempotenz ist wichtig. Aber um idempotent zu sein, muss man einen eindeutigen Schlüssel (oder eine Reihe von Schlüsseln) haben. Wenn der eindeutige Schlüssel in einem POST-Aufruf zweimal angegeben wird, sollte der zweite einen Fehler erzeugen. In einem PUT-Aufruf sollte er das Ressource erstellen/aktualisieren/ersetzen. Es ist möglich, einen POST-Aufruf ohne einen eindeutigen Schlüssel durchzuführen (es wird einfach jedes Mal eine neue Ressource erstellt). Es ist jedoch nicht möglich, einen PUT-Aufruf ohne Schlüssel durchzuführen.
0 Stimmen
All diese Diskussionen über die Idempotenz von PUT und das Fehlen dieser Eigenschaft bei POST ignorieren das eigentliche Problem. Der Browser wird bei beiden, sogar bei POST, erneut versuchen, wenn die Verbindung vom Server geschlossen wird. Daher müssen Sie Ihre API so entwickeln, dass sie unabhhängig davon idempotent ist, damit Sie sich nicht beschweren können, wenn es passiert! :) Die Wahl der Methode ist fast belanglos. stackoverflow.com/questions/15155014/… w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.4