REST-API mit POST anstelle von GET

74

Nehmen wir an, ein Dienst bietet eine Funktion, die ich folgendermaßen nutzen kann:

GET /service/function?param1=value1&param2=value2

Ist es richtig zu sagen, dass ich es mit einer POST-Abfrage verwenden kann?

POST /service/function { param1 : value1, param2 : value2 }

Sind diese beiden Abfragen gleich? Kann ich auf jeden Fall die zweite Variante verwenden oder sollte in der Dokumentation ausdrücklich angegeben werden, dass ich sowohl GET- als auch POST-Abfragen verwenden kann?

Strang
quelle
4
Darauf gibt es keine allgemeine Antwort - es hängt von der individuellen Implementierung ab. Und GETund POST sollte eine andere Semantik haben, also lautet die allgemeine Antwort vielleicht "Ich hoffe nicht"
Damien_The_Unbeliever
2
RUHE und functionpasst nicht gut zusammen. Wenn eine URL enthält function, methododer command, ich rieche RPC
1
Wenn Ihr Ziel darin besteht, die Komplexität vor der URL-Struktur selbst zu verbergen, stören Sie sich nicht. Die Verwendung einer POSTMethode nur zum Aufräumen ist ein Missbrauch, POSTwenn Sie versuchen, den RESTful-Prinzipien zu folgen
Kristian
2
In einer HTTP-API, die nicht dem Standard entspricht, gibt es keine allgemeine Antwort darauf. Du kannst machen was immer du willst. Wenn es RESTful ist, können Sie keinen POST durchführen, wenn nicht dokumentiert ist, was die Ressource damit macht. In der Tat, wenn es RESTful ist, muss es HATEOAS verwenden, und Sie würden keine unerwartete Anfrage an irgendetwas stellen.
Pedro Werneck
Sie können oft die gleichen Endergebnisse erzielen, selbst wenn Sie verschiedene HTTP-Verben verwenden. Es hängt nur davon ab, was sich in Ihrem Routencontroller befindet und wie hoch der Rückgabewert ist. Trotzdem ist es gut, sich an Konventionen zu halten.
Stealthysnacks

Antworten:

42

Sie können APIusing nicht verwenden POSToder GETwenn sie nicht erstellt wurden, um diese Methoden separat aufzurufen. Zum Beispiel, wenn Ihre API sagt

/service/function?param1=value1&param2=value2

wird mit der GETMethode zugegriffen . Dann können Sie es nicht mit POSTmethod aufrufen, wenn es POSTvom Ersteller nicht als Methode angegeben wurde . Wenn Sie das tun, erhalten Sie möglicherweise den 405 Method not allowedStatus.

Im Allgemeinen müssen Sie in der POSTMethode den Inhalt im Hauptteil mit dem angegebenen Format senden, das beispielsweise in der content-typeKopfzeile beschrieben ist . application/jsonfür JSON-Daten.

Danach wird der Anforderungshauptteil am Serverende deserialisiert. Sie müssen also die serialisierten Daten vom Client übergeben und dies wird vom Serviceentwickler festgelegt.

Im Allgemeinen GETwird dies jedoch verwendet, wenn der Server einige Daten an den Client zurückgibt und keine Auswirkungen auf den Server hat, während POSTer zum Erstellen einer Ressource auf dem Server verwendet wird. Im Allgemeinen sollte es also nicht dasselbe sein.

Sachin
quelle
Sollte der Server den content-typeHeader validieren ? Was ist, wenn Header Content-Type: application/x-www-form-urlencodedund Inhalt sind JSON?
Suhail Gupta
Bei GET-Anforderungen ist die Länge einer URL jedoch begrenzt (die maximale URL-Länge beträgt 2048 Zeichen). Wenn ich also eine Anfrage an die API senden möchte, deren Parameter möglicherweise eine lange Zeichenfolge (JSON) ist, sollte ich POST anstelle von GET verwenden.
Gordon
@gordie, ja, wenn Ihre API-Anfrage groß ist, sollten Sie POST verwenden, mit dem Sie den Anfragetext senden können. Im Allgemeinen benötigt die GETAPI nicht so viele Parameter oder JSON-Anforderungen.
Sachin
67

Nur um zu überprüfen, RESThat bestimmte Eigenschaften, die ein Entwickler folgen sollte, um es zu machen RESTful:

Was ist REST?

Laut Wikipedia:

Der REST-Architekturstil beschreibt die folgenden sechs Einschränkungen, die auf die Architektur angewendet werden, während die Implementierung der einzelnen Komponenten frei gestaltet werden kann:

  • Client-Server: Server sind nicht mit der Benutzeroberfläche oder dem Benutzerstatus befasst, sodass Server einfacher und skalierbarer sein können.
  • Statuslos: Die Client-Server-Kommunikation wird weiter eingeschränkt, da zwischen den Anforderungen kein Client-Kontext auf dem Server gespeichert wird.
  • Zwischenspeicherbar: Antworten müssen sich implizit oder explizit als zwischenspeicherbar definieren oder nicht, um zu verhindern, dass Clients veraltete oder unangemessene Daten als Antwort auf weitere Anforderungen wiederverwenden.
  • Schichtsystem: Ein Client kann normalerweise nicht feststellen, ob er direkt mit dem Endserver oder einem Vermittler verbunden ist. Zwischenserver können die Skalierbarkeit des Systems verbessern, indem sie den Lastausgleich ermöglichen und gemeinsam genutzte Caches bereitstellen.
  • Code on Demand (optional): Server können die Funktionalität eines Clients durch Übertragung von ausführbarem Code vorübergehend erweitern oder anpassen.
  • Einheitliche Schnittstelle: Die unten beschriebene einheitliche Schnittstelle zwischen Clients und Servern vereinfacht und entkoppelt die Architektur, sodass sich jedes Teil unabhängig entwickeln kann. (dh HTTP GET, POST, PUT, PATCH, DELETE)

Was die Verben tun sollen

Der SO-Benutzer Daniel Vasallo hat die Verantwortlichkeiten dieser Methoden in der Frage Grundlegendes zu REST: Verben, Fehlercodes und Authentifizierung gut dargelegt :

Beim Umgang mit einer Sammlungs-URI wie: http://example.com/resources/

GET: Listen Sie die Mitglieder der Sammlung zusammen mit ihren Mitglieds-URIs für die weitere Navigation auf. Listen Sie zum Beispiel alle zum Verkauf stehenden Autos auf.

PUT: Bedeutung definiert als "Ersetzen der gesamten Sammlung durch eine andere Sammlung".

POST: Erstellen Sie einen neuen Eintrag in der Sammlung, in dem die ID automatisch von der Sammlung zugewiesen wird. Die erstellte ID ist normalerweise Teil der von dieser Operation zurückgegebenen Daten.

LÖSCHEN: Bedeutung definiert als "Löschen der gesamten Sammlung".

Um Ihre Frage zu beantworten:

Ist es richtig zu sagen, dass ich es mit einer POST-Abfrage verwenden kann? ...

Sind diese beiden Abfragen gleich? Kann ich auf jeden Fall die zweite Variante verwenden oder sollte in der Dokumentation ausdrücklich angegeben werden, dass ich sowohl GET- als auch POST-Abfragen verwenden kann?

Wenn Sie einen einfachen alten RPC-API-Aufruf schreiben, können diese technisch ausgetauscht werden, solange sich die Seite des Verarbeitungsservers zwischen beiden Aufrufen nicht unterscheidet. Damit der Aufruf jedoch REST-fähig ist, sollte der Aufruf des Endpunkts über die GETMethode eine andere Funktionalität (das Abrufen von Ressourcen) als die POSTMethode (das Erstellen neuer Ressourcen) aufweisen.

Randnotiz: Es gibt einige Debatten darüber, ob POSTauch zum Aktualisieren von Ressourcen verwendet werden darf oder nicht ... obwohl ich das nicht kommentiere, sage ich Ihnen nur, dass einige Leute ein Problem mit diesem Punkt haben.

Kristian
quelle
6
Es scheint also, dass REST-API-Spezifikationen nicht für reale Fälle bereit sind, wenn wir aus verschiedenen Gründen (URL-Längenbeschränkungen, keine Unterstützung für GET in vielen Frameworks usw.) Ein anderes Verb anstelle von GET zum Abrufen der Liste von Entitäten verwenden möchten .). Dies bedeutet, dass es viele hackige, inkonsistente Lösungen gibt, um das Problem zu umgehen, während es keine Spezifikationen gibt, die den Entwicklern helfen könnten.
JustAMartin
60

Ich verwende POST body aus folgenden Gründen für alle nicht trivialen Apps und Branchen-Apps:

  1. Sicherheit - Wenn wir GET mit Abfragezeichenfolgen und https verwenden, können die Abfragezeichenfolgen in Serverprotokollen gespeichert und als Verweislinks weitergeleitet werden. Beide sind jetzt für Server- / Netzwerkadministratoren und die nächste Domain sichtbar, zu der der Benutzer nach dem Verlassen Ihrer App gegangen ist. Wenn wir also eine Anfrage mit vertraulichen PII-Daten wie dem Namen eines Kunden senden, ist dies möglicherweise nicht erwünscht.
  2. Maximale Länge der URL - Kein großes Problem, aber bei einigen Browsern ist die Länge begrenzt. Wenn wir also mehrere Elemente in unserer URL haben, wie z. B. Abfrage, Paging, zurückzugebende Felder usw.
  3. POST wird standardmäßig nicht zwischengespeichert. Einige sagen, dass Caching erwünscht ist; Wie oft wird jedoch genau derselbe Satz von Suchkriterien für genau dieses Objekt für diesen genauen Kunden auftreten, bevor der Cache ohnehin abläuft?

Übrigens habe ich auch die Felder, die zurückgegeben werden sollen, in meinen POST-Text eingefügt, da ich meine Feldnamen möglicherweise nicht offenlegen möchte. Sicherheit ist wie eine Zwiebel; es hat viele schichten und bringt uns zum weinen!

Scott Peal
quelle
3
Abfragezeichenfolgen werden normalerweise unabhängig vom Anforderungstyp in Webserverprotokollen gespeichert. Wenn Sie der Meinung sind, dass POST sicherer ist, weil Sie einige Dinge nicht sehen können, irren Sie sich. Caching ist etwas völlig anderes.
Phil
9
Ich denke , Scotts Punkt war , dass anstelle von GET unter Verwendung von POST, die Sie nicht Abfrage - Strings verwenden müssen , um überhaupt .
Nexus
2
Downvoted, Die Frage bezieht sich speziell auf REST, je nachdem, wie das OP es markiert hat. Diese Antwort ist in diesem Zusammenhang irrelevant, da es sich definitiv nicht um REST handelt.
Nathan Hughes
Wie können wir in diesem Fall unterscheiden, ob ein POST-Aufruf das Objekt erstellen oder die Antwort abrufen soll?
Noushad
Es ist bedauerlich, dass der HTTP-Dienst von Angular die Übertragung eines Körpers mit einem GET nicht zulässt, was das Problem lösen würde, wenn eine Site auf Webservern gehostet wird, die einen Körper auf einem GET akzeptieren!
Dave Boal
14

Denk darüber nach. Wenn Ihr Client eine GET-Anforderung an einen URI X sendet, heißt es auf dem Server: "Ich möchte eine Darstellung der Ressource in X, und dieser Vorgang sollte nichts auf dem Server ändern." In einer PUT-Anfrage heißt es: "Ich möchte, dass Sie die bei X befindliche Ressource durch die neue Entität ersetzen, die ich Ihnen im Hauptteil dieser Anfrage gebe." In einer DELETE-Anfrage heißt es: "Ich möchte, dass Sie die bei X befindliche Ressource löschen." Ein PATCH sagt: "Ich gebe Ihnen diesen Unterschied, und Sie sollten versuchen, ihn auf die Ressource bei X anzuwenden und mir zu sagen, ob er erfolgreich ist." Ein POST sagt jedoch: "Ich sende Ihnen diese Daten, die der Ressource bei X untergeordnet sind, und wir haben eine vorherige Vereinbarung darüber getroffen, was Sie damit tun sollen."

Wenn Sie nicht irgendwo dokumentiert haben, dass die Ressource einen POST erwartet und etwas damit macht, ist es nicht sinnvoll, einen POST an ihn zu senden und zu erwarten, dass er sich wie ein GET verhält.

REST basiert auf dem standardisierten Verhalten des zugrunde liegenden Protokolls, und POST ist genau die Methode, die für eine nicht standardisierte Aktion verwendet wird. Das Ergebnis einer GET-, PUT- und DELETE-Anforderung ist im Standard klar definiert, POST jedoch nicht. Das Ergebnis eines POST ist dem Server untergeordnet. Wenn also nicht dokumentiert ist, dass Sie POST verwenden können, um etwas zu tun, müssen Sie davon ausgehen, dass dies nicht möglich ist.

Pedro Werneck
quelle
10

Es ist schön, dass REST HTTP-Verben (wie sie definiert wurden) Bedeutung verleiht, aber ich stimme Scott Peal lieber zu.

Hier ist auch ein Punkt aus der erweiterten Erklärung von WIKI auf POST-Anfrage :

Es gibt Zeiten, in denen HTTP GET selbst für den Datenabruf weniger geeignet ist. Ein Beispiel hierfür ist, wenn in der URL viele Daten angegeben werden müssten. Browser und Webserver können die Länge der URL einschränken, die sie ohne Kürzung oder Fehler verarbeiten. Die prozentuale Codierung reservierter Zeichen in URLs und Abfragezeichenfolgen kann deren Länge erheblich erhöhen. Während Apache HTTP Server bis zu 4.000 Zeichen in einer URL verarbeiten kann, [5] ist Microsoft Internet Explorer in jeder URL auf 2.048 Zeichen beschränkt. [6] Ebenso sollte HTTP GET nicht verwendet werden, wenn vertrauliche Informationen wie Benutzernamen und Kennwörter zusammen mit anderen Daten übermittelt werden müssen, damit die Anforderung abgeschlossen werden kann. Selbst wenn HTTPS verwendet wird, wird verhindert, dass die Daten während der Übertragung abgefangen werden, der Browserverlauf und der Webserver. ' s Protokolle enthalten wahrscheinlich die vollständige URL im Klartext, die angezeigt werden kann, wenn eines der Systeme gehackt wird. In diesen Fällen sollte HTTP POST verwendet werden. [7]

Ich konnte dem REST-Team nur empfehlen, eine sicherere Verwendung des HTTP-Protokolls in Betracht zu ziehen, um zu vermeiden, dass Verbraucher mit nicht sicheren "bewährten Verfahren" zu kämpfen haben.

user7071799
quelle
1
Dies bietet im Vergleich zu Scott Peals Antwort nicht wirklich etwas Neues . Sie haben nur Wiki / bereitgestellt und Link zitiert und diesbezüglich: Während ein Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert.
Murmel
3

In REST hat jedes HTTP-Verben seinen Platz und seine Bedeutung.

Zum Beispiel,

  • GET soll die 'Ressource (n)' abrufen, auf die in der URL verwiesen wird.

  • POST soll das Backend anweisen, eine Ressource des Typs zu erstellen, auf den in der URL verwiesen wird. Sie können die POST-Operation mit Parametern oder zusätzlichen Daten im Hauptteil des POST-Aufrufs ergänzen.

In Ihrem Fall sollte es sich um eine GET-Operation anstelle einer POST-Operation handeln, da Sie daran interessiert sind, die Informationen mithilfe einer Abfrage abzurufen.

Dieses Wiki kann helfen , die Dinge weiter zu klären.

Ich hoffe das hilft!

Ming Chan
quelle
2

Wenn ich die Frage richtig verstehe, muss er eine REST GET-Aktion ausführen, fragt sich jedoch, ob das Senden von Daten über die HTTP-POST-Methode in Ordnung ist.

Wie Scott in seiner Antwort zuvor ausführlich dargelegt hatte, gibt es viele gute Gründe, Eingabedaten zu POSTEN. Meiner Meinung nach sollte dies so erfolgen, wenn die Qualität der Lösung oberste Priorität hat.

Vor einiger Zeit haben wir eine REST-API erstellt, um Benutzer zu authentifizieren, Benutzernamen / Passwort zu verwenden und ein Zugriffstoken zurückzugeben. Die API ist unter TLS verschlüsselt, jedoch dem öffentlichen Internet ausgesetzt. Nachdem wir verschiedene Optionen evaluiert hatten, wählten wir HTTP POST für die REST-Methode "GET Access Token", da dies die einzige Möglichkeit ist, Sicherheitsstandards zu erfüllen.

Hong Huo
quelle
1

POST kann anstelle von GET verwendet werden, wenn Sie bestimmte Gründe dafür haben und es ordnungsgemäß verarbeiten. Ich verstehe, dass es nicht speziell RESTy ist, aber wenn Ihre Daten eine Reihe von Leerzeichen, kaufmännischen Und- und Schrägstrichen usw. enthalten (z. B. ein Produktmodell wie Amazon), kann der Versuch, dies zu codieren und zu decodieren, mehr Probleme bereiten, als es wert ist, anstatt nur vorab jsonifizieren. Stellen Sie jedoch sicher, dass Sie die richtigen Antwortcodes zurückgeben und Ihre Aktivitäten stark kommentieren, da dies kein typischer Anwendungsfall für POST ist.

user12131170
quelle