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" erfordert, dass nicht idempotente Aktionen per POST gesendet werden. Dies ist eine nicht idempotente Aktion.
- Es ist einfacher, diese App zu entwickeln und zu debuggen, wenn die Anforderungsparameter in der URL vorhanden sind.
- Die API ist nicht für eine breite Verwendung vorgesehen.
- Es scheint, als würde das Erstellen einer POST-Anfrage ohne Text etwas mehr Arbeit
Content-Length: 0
erfordern , z. B. muss ein Header explizit hinzugefügt werden. - Es scheint mir auch, dass ein POST ohne Body den Erwartungen der meisten Entwickler- und HTTP-Frameworks etwas 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 sollten, eine andere Aktion als das Abrufen durchzuführen. Diese Methoden sollten als "sicher" angesehen werden. Auf diese Weise können Benutzeragenten andere Methoden wie POST, PUT und DELETE auf besondere Weise darstellen, sodass der Benutzer darauf aufmerksam gemacht wird, dass eine möglicherweise unsichere Aktion angefordert wird.
...
Methoden können auch die Eigenschaft "Idempotenz" haben, da (abgesehen von Fehler- oder Ablaufproblemen) die Nebenwirkungen von N> 0 identischen Anforderungen dieselben sind wie für eine einzelne Anforderung. Die Methoden GET, HEAD, PUT und DELETE teilen diese Eigenschaft. Außerdem sollten die Methoden OPTIONS und TRACE KEINE Nebenwirkungen haben und sind daher von Natur aus idempotent.
Antworten:
Wenn die Aktion nicht idempotent, dann Sie muss verwenden
POST
. Wenn Sie dies nicht tun, bitten Sie nur um Ärger auf der ganzen Linie.GET
,PUT
UndDELETE
sind Verfahren erforderlich sein idempotent. Stellen Sie sich vor, was in Ihrer Anwendung passieren würde, wenn der Client jede möglicheGET
Anforderung für Ihren Service vorab abrufen würde. Wenn dies für den Client sichtbare Nebenwirkungen verursachen würde, stimmt etwas nicht.Ich bin damit einverstanden, dass das Senden eines
POST
mit einer Abfragezeichenfolge, jedoch ohne Text, seltsam erscheint, aber ich denke, dass dies in einigen Situationen angemessen sein kann.Stellen Sie sich den Abfrageteil einer URL als Befehl an die Ressource vor, um den Umfang der aktuellen Anforderung einzuschränken. Normalerweise werden Abfragezeichenfolgen verwendet, um eine
GET
Anfrage zu sortieren oder zu filtern (wie?page=1&sort=title
), aber ich nehme an, dass es sinnvoll istPOST
, auch den Umfang zu begrenzen (vielleicht wie?action=delete&id=5
).quelle
/action?response_format=json
)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 vollkommen logisch: URLs, einschließlich ihres Abfragezeichenfolgenteils, dienen zum Auffinden von Ressourcen. Während HTTP-Methodenverben (POST - und sein optionaler Anforderungsinhalt) dazu dienen, Aktionen anzugeben oder was mit Ressourcen zu tun ist . Dies sollten orthogonale Bedenken sein. (Für den Sonderfall von ContentType = application / x-www-form-urlencoded sind sie jedoch keine besonders orthogonalen Bedenken, siehe Anmerkung 2 unten.)
Hinweis 1: In der HTTP-Spezifikation (1.1) wird nicht angegeben, dass sich Abfrageparameter und Inhalt 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 Sie nichts 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 bedingter Logik 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 Art ist, wie Benutzer auf Ihre Webanwendung zugreifen, und application / x-www-form-urlencoded der Inhaltstyp ist, den sie veröffentlichen, 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 eine Reihe von Parametern und nicht als Ressourcenspeicherort interpretieren. [Dies ist derselbe Punkt der Nützlichkeit, den Powerlord angesprochen hat. Es kann schwierig sein, Webformulare zu verwenden, um Inhalte auf Ihrem Server zu veröffentlichen. Nur ein bisschen anders erklärt.]
Hinweis 3: Wofür sind Abfragezeichenfolgen ursprünglich gedacht? RFC 3986 definiert HTTP-Abfragezeichenfolgen als URI-Teil, der als nicht hierarchische Methode zum Auffinden einer Ressource dient.
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. Die RESTful-Architektur befasst sich mit anderen Eigenschaften des Systems, wie der Cachefähigkeit von Ressourcen, dem Design der Ressourcen selbst (deren Verhalten, Fähigkeiten und Darstellungen) und der Frage, ob die Idempotenz erfüllt ist. Mit anderen Worten: Erzielen eines Designs, das in hohem Maße mit dem HTTP-Protokoll und seinen HTTP-Methodenverben kompatibel ist. :-) (Mit anderen Worten, ist RESTful - Architektur nicht sehr presciptive mit , wie die Ressourcen befinden .)
Schlussbemerkung: Manchmal werden Abfrageparameter für andere Dinge verwendet, bei denen weder Ressourcen gefunden noch Inhalte codiert werden. Haben Sie jemals einen Abfrageparameter wie 'PUT = true' oder 'POST = true' gesehen? Dies sind Problemumgehungen für Browser, in denen Sie keine PUT- und POST-Methoden verwenden können. Während solche Parameter als Teil der URL-Abfragezeichenfolge (auf der Leitung) gesehen werden, argumentiere ich, dass sie nicht Teil der URL-Abfrage im Geiste sind .
quelle
Du willst Gründe? Hier ist eine:
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 Formularübermittlung
quelle
method
POST ist, wird nicht erwähnt, dass der URI in den Formularen geändert wirdaction
. Und jeder URI kann natürlich bereits einen Abfragezeichenfolgen-Teil enthalten./Books?bookCode=1234
. Der Webserver erhält POST-Formularvariablen und eine Abfragezeichenfolge.Aus programmatischer Sicht packt der Client Parameter zusammen, hängt sie an die URL an und führt einen POST gegen einen GET durch. Auf der Serverseite werden eingehende Parameter aus dem Querystring anstelle der gesendeten Bytes ausgewertet. Im Grunde ist es eine Wäsche.
Es kann Vor- / Nachteile geben, wie bestimmte Clientplattformen mit POST- und GET-Routinen in ihrem Netzwerkstapel arbeiten und wie der Webserver mit diesen Anforderungen umgeht. Abhängig von Ihrer Implementierung ist ein Ansatz möglicherweise effizienter als der andere. Zu wissen, dass dies Ihre Entscheidung hier leiten würde.
Aus Sicht eines Programmierers bevorzuge ich es jedoch, entweder einen POST mit allen Parametern im Textkörper oder einen GET mit allen Parametern in der URL zuzulassen und URL-Parameter bei jeder POST-Anforderung explizit zu ignorieren. Es vermeidet Verwirrung.
quelle
Ich würde denken, dass es immer noch ziemlich RESTful sein könnte, Abfrageargumente zu haben, die die Ressource auf der URL identifizieren, während die Nutzdaten des Inhalts auf den POST-Body beschränkt bleiben. Dies scheint die Überlegungen zu "Was sende ich?" versus "An wen sende ich es?".
quelle
Das REST- Camp hat einige Leitprinzipien, mit denen wir die Art und Weise, wie wir HTTP-Verben verwenden, standardisieren können. Dies ist hilfreich, wenn Sie gerade RESTful-APIs erstellen.
Kurz gesagt: GET sollte schreibgeschützt sein, dh keine Auswirkungen auf den Serverstatus haben. POST wird verwendet, um eine Ressource auf dem Server zu erstellen. PUT wird zum Aktualisieren oder Erstellen einer Ressource verwendet. DELETE wird zum Löschen einer Ressource verwendet.
Mit anderen Worten, wenn Ihre API-Aktion den Serverstatus ändert, empfiehlt REST, POST / PUT / DELETE, jedoch nicht GET zu verwenden.
Benutzeragenten verstehen normalerweise, dass das Ausführen mehrerer POSTs schlecht ist und warnen davor, da die Absicht des POST darin besteht, den Serverstatus zu ändern (z. B. für Waren an der Kasse zu bezahlen), und Sie möchten dies wahrscheinlich nicht zweimal tun!
Vergleichen Sie mit einem GET, das Sie oft nach Belieben ausführen können (idempotent).
quelle
Ich stimme zu - es ist wahrscheinlich sicherer, eine GET-Anfrage zu verwenden, wenn Sie nur Daten in der URL und nicht im Text übergeben. In dieser ähnlichen Frage finden Sie einige zusätzliche Ansichten zum gesamten POST + GET-Konzept.
quelle