627 Stimmen

HTTP POST mit URL-Abfrageparametern - gute Idee oder nicht?

Ich entwerfe eine API, die über HTTP läuft, und ich frage mich, ob die Verwendung des HTTP POST-Befehls, aber nur mit URL-Abfrageparametern und ohne Anfragebody, ein guter Weg ist, um zu gehen.

Erwägungen:

  • "Gutes Webdesign" verlangt, dass nicht-idempotente Aktionen per POST gesendet werden. Dies ist eine nicht-idempotente Aktion.
  • Es ist einfacher, diese Anwendung zu entwickeln und zu debuggen, wenn die Anfrageparameter in der URL enthalten sind.
  • Die API ist nicht für eine breite Anwendung gedacht.
  • Es scheint, dass eine POST-Anfrage ohne Body etwas mehr Arbeit erfordert, z.B. eine Content-Length: 0 Kopfzeile muss explizit hinzugefügt werden.
  • Es scheint mir auch, dass ein POST ohne Body den Erwartungen der meisten Entwickler und HTTP-Frameworks widerspricht.

Gibt es weitere Fallstricke oder Vorteile bei der Übermittlung von Parametern bei einer POST-Anforderung über die URL-Abfrage und nicht über den Anforderungskörper?

Bearbeiten: Der Grund, warum dies in Erwägung gezogen wird, ist, dass die Operationen nicht idempotent sind und andere Nebeneffekte als das Abrufen haben. Siehe die HTTP-Spezifikation :

Insbesondere wurde die Konvention festgelegt, dass die Methoden GET und HEAD Methoden NICHT die Bedeutung haben sollen Bedeutung haben, eine andere Aktion als das Abrufen. Diese Methoden sollten als "sicher" angesehen werden. Dies erlaubt den Benutzer Agenten, andere Methoden darzustellen, wie POST, PUT und DELETE, in einer speziellen Art und Weise darzustellen, so dass dem Benutzer die darauf aufmerksam gemacht wird, dass eine möglicherweise unsichere Aktion angefordert wird.

...

Methoden können auch die Eigenschaft haben "Idempotenz" haben, indem sie (abgesehen von Fehler- oder Verfallsproblemen) die Nebeneffekte von N > 0 identischen Anfragen die gleichen sind wie bei einer einzigen Anfrage. Die Methoden GET, HEAD, PUT und DELETE haben diese Eigenschaft gemeinsam. Außerdem die Methoden OPTIONS und TRACE SHOULD KEINE Seiteneffekte haben und sind daher von Natur aus idempotent.

20 Stimmen

Warum sollte man POST überhaupt verwenden, wenn man im Textkörper keine Daten bereitstellt?

154 Stimmen

Denn der Vorgang ist nicht idempotent.

1 Stimmen

Was versuchen Sie zu tun, das nicht idempotent und keine echte POST ist? Es scheint, dass entweder Ihr REST-Design einige Probleme hat oder die Interaktion, die Sie zu schaffen versuchen, eignet sich nicht für eine RESTful-Schnittstelle. Vielleicht können wir Ihnen bei der Formulierung einer besseren REST-Schnittstelle helfen, wenn Sie mehr Details angeben.

373voto

Don McCaughey Punkte 8962

Wenn Ihre Handlung nicht idempotent ist, dann haben Sie MUSS verwenden. POST . Wenn Sie das nicht tun, können Sie sich später nur Ärger einhandeln. GET , PUT y DELETE Methoden sind erforderlich um idempotent zu sein. Stellen Sie sich vor, was in Ihrer Anwendung passieren würde, wenn der Client jede mögliche Datei im Voraus abrufen würde. GET Anfrage für Ihren Dienst - wenn dies zu für den Kunden sichtbaren Nebenwirkungen führt, dann stimmt etwas nicht.

Ich stimme zu, dass das Senden einer POST mit einer Abfragezeichenfolge, aber ohne Textkörper, scheint seltsam, aber ich denke, dass es in einigen Situationen angemessen sein kann.

Betrachten Sie den Abfrageteil einer URL als einen Befehl an die Ressource, den Umfang der aktuellen Anfrage einzuschränken. Normalerweise werden Abfragezeichenfolgen zum Sortieren oder Filtern einer GET Anfrage (wie ?page=1&sort=title ), aber ich nehme an, dass es bei einem POST um auch den Geltungsbereich zu begrenzen (vielleicht wie ?action=delete&id=5 ).

5 Stimmen

Ich habe diese Antwort für diesen speziellen Fall gewählt, aber ich denke, dass das Argument von R. Bemrose für öffentliche APIs überzeugend ist.

6 Stimmen

Ich glaube nicht, dass seine Antwort wirklich korrekt ist. Wenn Sie die URL-Parameter für Ihr Formular kennen, wenn die HTML-Seite an den Client gesendet wird, können Sie diese URL-Parameter an das Action-Attribut des Formulars anhängen, andernfalls kann JavaScript die URL-Parameter festlegen, wenn das Formular übermittelt wird.

3 Stimmen

Wie wäre es, eine XML-Datei in eine URL mit Abfrageparametern zu posten? Ist das möglich?

184voto

Tim Lovell-Smith Punkte 14066

Alle haben Recht: Bleiben Sie bei POST für nicht-idempotente Anfragen.

Wie wäre es, wenn Sie sowohl einen URI-Abfrage-String als auch den Inhalt der Anfrage verwenden? Nun, das ist gültiges HTTP (siehe Anmerkung 1), also warum nicht?!

Es ist auch völlig logisch: URLs, einschließlich ihres Query-String-Teils, sind für Auffinden von Ressourcen. Die Verben der HTTP-Methode (POST - und der optionale Inhalt der Anfrage) dienen der Angabe von Aktionen bzw. was zu tun ist mit Ressourcen. Das sollten orthogonale Anliegen sein. (Für den Sonderfall von ContentType=application/x-www-form-urlencoded sind sie jedoch nicht schön orthogonal, siehe Anmerkung 2 unten).

Anmerkung 1: Die HTTP-Spezifikation (1.1) besagt nicht, dass sich Abfrageparameter und Inhalt bei einem HTTP-Server, der POST- oder PUT-Anfragen annimmt, gegenseitig ausschließen. Es steht also jedem Server frei, beides zu akzeptieren. Das heißt, wenn Sie den Server schreiben, hindert Sie nichts daran, beides zu akzeptieren (außer vielleicht ein unflexibles Framework). Im Allgemeinen kann der Server Abfragezeichenfolgen nach beliebigen Regeln interpretieren. Er kann sie sogar mit bedingter Logik interpretieren, die sich auch auf andere Header wie Content-Type bezieht, was zu Anmerkung 2 führt:

Anmerkung 2: Wenn ein Webbrowser ist der primäre Weg, auf dem Menschen auf Ihre Webanwendung zugreifen, und anwendung/x-www-form-urlencoded der Content-Type ist, der gepostet wird, dann können Sie sollte den Regeln für diesen Content-Type folgen. Und die Regeln für application/x-www-form-urlencoded sind sehr viel spezifischer (und, offen gesagt, ungewöhnlich): In diesem Fall müssen Sie den URI als eine Reihe von Parametern interpretieren und nicht als Speicherort einer Ressource. [Dies ist derselbe Punkt der Nützlichkeit, den Powerlord angesprochen hat: dass es schwierig sein kann, Webformulare zu verwenden, um Inhalte an Ihren Server zu POSTen. Nur ein wenig anders erklärt].

Anmerkung 3: Wofür sind Query-Strings ursprünglich gedacht? RFC 3986 definiert HTTP-Query-Strings als einen URI-Teil, der als nicht-hierarchische Methode zum Auffinden einer Ressource dient.

Für den Fall, dass Leser, die diese Frage stellen, fragen möchten, was eine gute RESTful-Architektur ist: Das RESTful-Architekturmuster verlangt nicht, dass URI-Schemata auf eine bestimmte Weise funktionieren. Die RESTful-Architektur befasst sich mit anderen Eigenschaften des Systems, wie der Cache-Fähigkeit von Ressourcen, dem Design der Ressourcen selbst (ihr Verhalten, ihre Fähigkeiten und ihre Darstellungen) und ob die Idempotenz erfüllt ist. Mit anderen Worten, es geht darum, ein Design zu erreichen, das mit dem HTTP-Protokoll und seinen HTTP-Methodenverben in hohem Maße kompatibel ist :-) (Mit anderen Worten, die RESTful-Architektur ist nicht sehr anspruchsvoll in Bezug auf die Art und Weise, wie die Ressourcen Standort .)

Abschließende Anmerkung: Manchmal werden Abfrageparameter für andere Dinge verwendet, die weder mit dem Auffinden von Ressourcen noch mit der Codierung von Inhalten zu tun haben. Haben Sie jemals einen Abfrageparameter wie 'PUT=true' oder 'POST=true' gesehen? Dies sind Behelfslösungen für Browser, die die Verwendung von PUT- und POST-Methoden nicht zulassen. Während solche Parameter als Teil des URL-Abfrage-Strings (auf dem Draht) angesehen werden, argumentiere ich, dass sie nicht Teil der URL-Abfrage sind im Geiste .

18voto

jro Punkte 7212

Aus programmtechnischer Sicht bedeutet dies für den Client, dass die Parameter verpackt und an die URL angehängt werden und ein POST im Gegensatz zu einem GET durchgeführt wird. Auf der Serverseite werden die eingehenden Parameter aus dem Querystring anstelle der gesendeten Bytes ausgewertet. Im Grunde genommen ist es ein Reinfall.

Vor- und Nachteile könnten sich daraus ergeben, wie bestimmte Client-Plattformen mit POST- und GET-Routinen in ihrem Netzwerk-Stack arbeiten und wie der Webserver mit diesen Anfragen umgeht. Je nach Ihrer Implementierung kann der eine Ansatz effizienter sein als der andere. Dies zu wissen, würde Ihre Entscheidung hier beeinflussen.

Aus der Sicht eines Programmierers ziehe ich es jedoch vor, entweder einen POST mit allen Parametern im Body oder einen GET mit allen Parametern in der URL zuzulassen und die URL-Parameter bei jeder POST-Anfrage ausdrücklich zu ignorieren. Das vermeidet Verwirrung.

12voto

swizzcheez Punkte 101

Ich würde denken, dass es immer noch ziemlich RESTful sein könnte, um Abfrageargumente zu haben, die die Ressource auf der URL identifizieren, während die Inhaltsnutzlast auf den POST-Body beschränkt bleibt. Dies scheint die Überlegungen "Was sende ich?" und "An wen sende ich es?" zu trennen.

6 Stimmen

Die Frage bezog sich nicht auf REST.

4 Stimmen

@user359996 Nicht alle HTTP-APIs sind RESTful. Die meisten APIs, die das von sich behaupten, sind es in Wirklichkeit nicht. Außerdem ist REST auch nicht nur auf HTTP beschränkt.

6voto

saille Punkte 8687

El REST camp haben einige Leitprinzipien, die wir verwenden können, um die Verwendung von HTTP-Verben zu standardisieren. Dies ist hilfreich bei der Erstellung von RESTful-APIs, wie Sie es gerade tun.

Kurz und bündig: GET sollte Read Only sein, d.h. keine Auswirkungen auf den Serverstatus haben. POST wird verwendet, um eine Ressource auf dem Server zu erstellen. PUT wird verwendet, um eine Ressource zu aktualisieren oder zu erstellen. DELETE wird verwendet, um eine Ressource zu löschen.

Mit anderen Worten: Wenn Ihre API-Aktion den Serverzustand ändert, empfiehlt REST die Verwendung von POST/PUT/DELETE, aber nicht GET.

User-Agents wissen in der Regel, dass mehrere POSTs schlecht sind und warnen davor, weil der Zweck von POST darin besteht, den Serverstatus zu ändern (z. B. die Bezahlung von Waren an der Kasse), und das wollen Sie wahrscheinlich nicht zweimal tun!

Vergleichen Sie dies mit einem GET, das Sie beliebig oft durchführen können (idempotent).

15 Stimmen

Die REST-Lager sagen, dass man HTTP so verwenden sollte, wie es in der HTTP-Spezifikation definiert ist, d. h. RFC2616. Nicht mehr und nicht weniger.

1 Stimmen

@Darrel Referring ibm.com/developerworks/webservices/library/ws-restful : REST verlangt von den Entwicklern, HTTP-Methoden explizit und in einer Weise zu verwenden, die mit der Protokolldefinition vereinbar ist. Mit diesem grundlegenden REST-Designprinzip wird eine Eins-zu-Eins-Zuordnung zwischen CRUD-Operationen (create, read, update, delete) und HTTP-Methoden hergestellt. Gemäß dieser Abbildung: Um eine Ressource auf dem Server zu erstellen, verwenden Sie POST. Um eine Ressource abzurufen, verwenden Sie GET. Um den Status einer Ressource zu ändern oder sie zu aktualisieren, verwenden Sie PUT. Um eine Ressource zu entfernen oder zu löschen, verwenden Sie DELETE.

5 Stimmen

Entschuldigung, aber das ist schlichtweg falsch. REST erfordert die Einhaltung einer einheitlichen Schnittstelle. Wenn Sie HTTP verwenden, dann ist diese einheitliche Schnittstelle zum Teil in RFC 2616 definiert. In dieser Spezifikation gibt es keine Eins-zu-Eins-Zuordnung zwischen Erstellen, Lesen, Aktualisieren und Löschen und den HTTP-Methoden.

CodeJaeger.com

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

Powered by:

X