it-swarm.com.de

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

Ich entwerfe eine API für HTTP und frage mich, ob die Verwendung des Befehls HTTP POST, jedoch nur mit URL-Abfrageparametern und ohne Anforderungshauptteil, ein guter Weg ist.

Überlegungen:

  • "Gutes Webdesign" setzt voraus, dass nicht idempotente Aktionen per POST gesendet werden. Dies ist eine nicht idempotente Handlung.
  • Es ist einfacher, diese App zu entwickeln und zu debuggen, wenn die Anforderungsparameter in der URL vorhanden sind.
  • Die API ist nicht für die allgemeine Verwendung gedacht.
  • Es scheint, als würde das Erstellen einer POST -Anforderung ohne Text etwas mehr Arbeit erfordern, z. Ein Content-Length: 0 -Header muss explizit hinzugefügt werden.
  • Es scheint mir auch, dass ein POST ohne Text den Erwartungen der meisten Entwickler und HTTP-Frameworks ein wenig widerspricht.

Gibt es weitere Fallstricke oder Vorteile beim Senden von Parametern für eine POST -Anforderung über die URL-Abfrage anstelle des Anforderungshauptteils?

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

Insbesondere wurde die Konvention festgelegt, dass die Methoden GET und HEAD NICHT die Bedeutung haben DÜRFEN, eine andere Aktion als das Abrufen auszuführen. Diese Methoden sollten als "sicher" angesehen werden. Auf diese Weise können Benutzerprogramme andere Methoden wie POST, PUT und DELETE auf besondere Weise darstellen, sodass der Benutzer auf die Tatsache aufmerksam gemacht wird, dass eine möglicherweise unsichere Aktion angefordert wird.

...

Methoden können auch die Eigenschaft "idempotence" haben, dass (abgesehen von Fehler- oder Ablaufproblemen) die Nebenwirkungen von N> 0 identischen Anforderungen die gleichen sind wie bei einer einzelnen Anforderung. Die Methoden GET, HEAD, PUT und DELETE teilen diese Eigenschaft. Die Methoden OPTIONS und TRACE SOLLTEN KEINE Nebenwirkungen haben und sind daher von Natur aus idempotent.

424
Steven Huwig

Wenn Ihre Handlung nicht idempotent ist, dann verwenden Sie MUSSPOST. Wenn Sie dies nicht tun, bitten Sie nur um Ärger auf der ganzen Linie. GET, PUT und 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 GET Anforderung für Ihren Service vorab abruft. Wenn dies zu Nebenwirkungen führen würde, die für den Client sichtbar sind, stimmt etwas nicht.

Ich bin damit einverstanden, dass das Senden von POST mit einer Abfragezeichenfolge, jedoch ohne Textkörper, seltsam erscheint, aber ich denke, dass dies in einigen Situationen angemessen sein kann.

Stellen Sie sich den Abfrageteil einer URL als Befehl zur Ressource vor, um den Umfang der aktuellen Anforderung zu begrenzen. In der Regel werden Abfragezeichenfolgen verwendet, um eine GET -Anforderung zu sortieren oder zu filtern (wie ?page=1&sort=title), aber ich nehme an, dass es bei POST Sinn macht, den Gültigkeitsbereich zu begrenzen (möglicherweise wie ?action=delete&id=5).

238
Don McCaughey

Jeder hat Recht: Bleiben Sie bei POST für nicht idempotente Anfragen.

Was ist mit der Verwendung einer URI-Abfragezeichenfolge und des Anforderungsinhalts? Nun, es ist gültiges HTTP (siehe Anmerkung 1), warum also nicht?

Es ist auch völlig logisch: URLs, einschließlich des Teils der Abfragezeichenfolge, dienen zum Auffinden von Ressourcen. Während HTTP-Methodenverben (POST - und deren optionaler Anforderungsinhalt) zum Angeben von Aktionen oder zum Behandeln von Ressourcen dienen. Das sollten orthogonale Bedenken sein. (Für den Sonderfall ContentType = application/x-www-form-urlencoded sind sie jedoch keine orthogonalen Probleme, siehe Anmerkung 2 unten.)

Hinweis 1: Die HTTP-Spezifikation (1.1) besagt nicht, dass sich Abfrageparameter und -inhalte für einen HTTP-Server, der POST- oder PUT-Anforderungen akzeptiert, gegenseitig ausschließen. Jeder Server kann also beide akzeptieren. Das heißt Wenn Sie den Server schreiben, hindert nichts Sie daran, beide zu akzeptieren (außer vielleicht einem unflexiblen Framework). Im Allgemeinen kann der Server Abfragezeichenfolgen nach beliebigen Regeln interpretieren. Es kann sie sogar mit Bedingungslogik interpretieren, die sich auch auf andere Header wie Content-Type bezieht, was zu Anmerkung 2 führt:

Hinweis 2: Wenn ein Webbrowser die primäre Methode ist, mit der Benutzer auf Ihre Webanwendung zugreifen, und application/x-www-form-urlencoded) ist der Inhaltstyp, den sie veröffentlichen, dann sollten Sie die Regeln für diesen Inhaltstyp befolgen . Und die Regeln für application/x-www-form-urlencoded sind viel spezifischer (und offen gesagt ungewöhnlich): In diesem Fall müssen Sie den URI als einen Satz von Parametern und nicht als einen Ressourcenstandort interpretieren. [Dies ist derselbe nützliche Punkt, den Powerlord angesprochen hat; Es ist möglicherweise schwierig, Webformulare zu verwenden, um POST Inhalte auf Ihren Server zu übertragen. Nur ein bisschen anders erklärt.]

Hinweis 3: Wozu dienen Abfragezeichenfolgen ursprünglich? RFC 3986 definiert HTTP-Abfragezeichenfolgen als URI-Teil, der als nicht hierarchische Methode zum Auffinden einer Ressource fungiert.

Falls Leser, die diese Frage stellen, fragen möchten, was eine gute RESTful-Architektur ist: Für das RESTful-Architekturmuster sind keine URI-Schemata erforderlich, um auf eine bestimmte Weise zu funktionieren. RESTful Architecture befasst sich mit anderen Eigenschaften des Systems, wie der Cachefähigkeit von Ressourcen, dem Design der Ressourcen selbst (ihrem Verhalten, ihren Fähigkeiten und Repräsentationen) und der Frage, ob die Idempotenz erfüllt ist. Oder mit anderen Worten, ein Design zu erzielen, das mit dem HTTP-Protokoll und dessen Satz von HTTP-Methodenverben in hohem Maße kompatibel ist. :-) (Mit anderen Worten, die RESTful-Architektur ist nicht sehr genau, wie sich die Ressourcen befinden .)

Letzte Anmerkung: Manchmal werden Abfrageparameter für noch andere Dinge verwendet, die weder Ressourcen lokalisieren noch Inhalt codieren. Haben Sie jemals einen Abfrageparameter wie 'PUT = true' oder 'POST = true' gesehen? Dies sind Problemumgehungen für Browser, bei denen Sie die Methoden PUT und POST nicht verwenden können. Während solche Parameter als Teil der URL-Abfragezeichenfolge (auf der Leitung) gesehen werden, behaupte ich, dass sie nicht Teil der URL-Abfrage im Geiste sind.

123

Du willst Gründe? Hier ist eins:

Ein Webformular kann nicht zum Senden einer Anfrage an eine Seite verwendet werden, die eine Mischung aus GET und POST verwendet. Wenn Sie die Methode des Formulars auf GET setzen, befinden sich alle Parameter in der Abfragezeichenfolge. Wenn Sie die Methode des Formulars auf POST setzen, befinden sich alle Parameter im Anforderungshauptteil.

Quelle: HTML 4.01-Standard, Abschnitt 17.13 Form Submission

62
Powerlord

Aus programmatischer Sicht packt der Client die Parameter, hängt sie an die URL an und führt ein POST im Vergleich zu einem GET durch. Auf der Serverseite werden eingehende Parameter vom Querystring ausgewertet und nicht von den bereitgestellten Bytes. Im Grunde ist es eine Wäsche.

Vor- und Nachteile können darin bestehen, wie bestimmte Client-Plattformen mit POST - und GET-Routinen in ihrem Netzwerkstapel arbeiten und wie der Webserver mit diesen Anforderungen umgeht. Abhängig von Ihrer Implementierung ist möglicherweise ein Ansatz effizienter als der andere. Das zu wissen, würde Ihre Entscheidung hier leiten.

Aus Sicht eines Programmierers bevorzuge ich es jedoch, entweder ein POST mit allen Parametern im Text oder ein GET mit allen Parametern in der URL zuzulassen und URL-Parameter mit jedem POST explizit zu ignorieren. Anfrage. Das vermeidet Verwirrung.

8
jro

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

6
swizzcheez

Das REST Camp hat einige Leitprinzipien, die wir verwenden können, um die Art und Weise zu standardisieren, wie wir HTTP-Verben verwenden. Dies ist hilfreich, wenn Sie RESTful-APIs wie folgt erstellen.

Kurz gesagt: GET sollte schreibgeschützt sein, d. H. Keine Auswirkung auf den Serverstatus haben. POST wird verwendet, um eine Ressource auf dem Server zu erstellen. PUT wird zum Aktualisieren oder Erstellen einer Ressource verwendet. Mit DELETE wird eine Ressource gelöscht.

Mit anderen Worten, wenn Ihre API-Aktion den Serverstatus ändert, empfiehlt REST die Verwendung von POST/PUT/DELETE, jedoch nicht von GET.

Benutzeragenten verstehen normalerweise, dass das Ausführen mehrerer POSTs schlecht ist und warnen davor, da die Absicht von POST darin besteht, den Serverstatus zu ändern (z. B. die Bezahlung von Waren an der Kasse), und Sie möchten dies wahrscheinlich nicht mach das zweimal!

Vergleichen Sie mit einem GET, das Sie oft machen können, wie Sie wollen (idempotent).

3
saille