389


116

URLクエリパラメータを使用したHTTP POST - お勧めかどうか

私はHTTP上で動作するようにAPIを設計しています、そしてHTTP POSTコマンドを使用するかどうか疑問に思っています、しかしURL問い合わせパラメータだけで要求本体なしで、行くための良い方法です。

考慮事項:

  • "良いWebデザイン"はPOSTを介して送信されるべきではないべきでないアクションを必要とします。 これは冪等ではありません。

  • 要求パラメーターがこのアプリの開発とデバッグを容易にする URLに存在します。

  • APIは広範囲に使用することを目的としていません。

  • ボディなしでPOSTリクエストを行うともう少し時間がかかるようです 仕事、例えば `+ Content-Length:0 +`ヘッダーを明示的に追加する必要があります。

  • また、身体のないPOSTは、ほとんどの人に少し反するように思えます 開発者とHTTPフレームワークの期待。

リクエストボディではなくURLクエリを介してPOSTリクエストでパラメータを送信することには、他に落とし穴や利点がありますか?

編集:これが考慮されている理由は、操作がべき等ではなく、検索以外の副作用があるためです。 http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html [HTTPの仕様]を参照してください。

_ _ 特に、GETメソッドとHEADメソッドには、検索以外のアクションを実行する意義があるべきではないという規約が確立されています。 これらの方法は「安全」と見なされるべきです。 これにより、ユーザーエージェントはPOST、PUT、DELETEなどの他のメソッドを特別な方法で表現できるようになり、ユーザーは恐らく危険なアクションが要求されているという事実を認識することができます。

…​

メソッドは(エラーや有効期限の問題を除けば)N> 0の同一リクエストの副作用が単一リクエストの場合と同じであるという点で、「べき等性」の特性を持つこともできます。 メソッドGET、HEAD、PUT、DELETEはこのプロパティを共有します。 また、OPTIONSメソッドとTRACEメソッドには副作用がないはずであるため、本質的にはべき等です。 _ _

7 Answer


210


アクションがdem等でない場合は、_POST + を使用する必要があります。 そうでなければ、あなたはただ問題を解決するよう求めているだけです。 `+ GET ++ PUT +、および `+ DELETE `メソッドはべき等である必要があります。 クライアントがサービスに対するすべての可能な「 GET +」リクエストをプリフェッチしていた場合、アプリケーションで何が起こるか想像してください-これがクライアントに見える副作用を引き起こすなら、何かが間違っています。

クエリ文字列を使用してボディなしで「+ POST +」を送信するのは奇妙に思えますが、状況によっては適切だと思います。

URLのクエリ部分は、現在のリクエストの範囲を制限するためのリソースへのコマンドと考えてください。 通常、クエリ文字列は、 `+ GET `リクエスト( `?page = 1&sort = title `など)のソートまたはフィルタリングに使用されますが、スコープを制限するために ` POST `で意味があると思われます(おそらく ` ?action = delete&id = 5 + `)。


108


誰もが正しい:冪等でない要求についてはPOSTに固執する。

URIクエリ文字列とリクエストコンテンツの両方を使用することについてはどうですか? それは有効なHTTPです(注1を参照)。

それはまた完全に論理的です:それらのクエリ文字列部分を含むURLは_locating_リソースのためのものです。 一方、HTTPメソッドの動詞(POST - とそのオプションのリクエストコンテンツ)はアクションを指定するためのもので、リソースを処理するためのものです。 それらは直交関係にあるべきです。 (ただし、ContentType = application / x-www-form-urlencodedの特殊なケースでは、それらは美しく直角の関係にはありません。下記の注2を参照してください。)

注意1:HTTP仕様(1.1)では、クエリパラメータとコンテンツがPOSTまたはPUT要求を受け付けるHTTPサーバーに対して相互に排他的であるとは述べられていません。 そのため、どのサーバーでも自由に両方を受け入れることができます。 すなわち サーバーを書いても、両方を受け入れることをやめさせるものは何もありません(柔軟性のないフレームワークを除いて)。 一般に、サーバーは必要な規則に従ってクエリ文字列を解釈できます。 Content-Typeのような他のヘッダも参照する条件付きロジックでそれらを解釈することさえできます。

注2:_web browser_があなたのWebアプリケーションにアクセスする主な方法で、* application / x-www-form-urlencoded *が投稿するContent-Typeの場合、そのContent-Typeの規則に従うべきです。 。 そして、application / x-www-form-urlencodedのルールはもっと具体的です(そして率直に言って、珍しいです):この場合、URIをリソースの場所ではなくパラメータのセットとして解釈する必要があります。 [これはPowerlordが提起した有用性と同じ点である。 Webフォームを使用してコンテンツをサーバーにPOSTするのは難しいかもしれません。 ちょっと違う説明をしてください。]

注3:もともとクエリ文字列は何ですか? RFC 3986では、HTTPクエリ文字列を、リソースを探すための非階層的な方法として機能するURI部分として定義しています。

この質問をしている読者が良いRESTfulアーキテクチャとは何かを尋ねたい場合、RESTfulアーキテクチャパターンはURIスキームが特定の方法で動作することを必要としません。 RESTfulアーキテクチャーは、リソースのキャッシュ可能性、リソース自体の設計(動作、機能、および表現)、そしてべき等性が満たされるかどうかなど、システムの他の特性にも関係します。 または言い換えれば、HTTPプロトコルとそのHTTPメソッド動詞のセットとの互換性が高い設計を実現することです。 :-)(言い換えれば、RESTfulアーキテクチャーはリソースがどのように配置されているかという点で非常に先見的ではありません。)

最後の注意:時々、クエリパラメータは、リソースを見つけることもコンテンツをエンコードすることもしていない他のことに使われることがあります。 'PUT = true’や 'POST = true’のようなクエリパラメータを見たことがありますか? これらはPUTおよびPOSTメソッドを使用することを許可していないブラウザのための回避策です。 そのようなパラメータはURLクエリ文字列の一部として(ワイヤ上で)見られますが、私はそれらがURLのクエリ_in_の一部ではないと主張します。


60


あなたは理由が欲しいですか? これが一つです:

Webフォームを使用して、GETとPOSTを組み合わせて使用​​するページにリクエストを送信することはできません。 フォームのメソッドをGETに設定した場合、すべてのパラメータはクエリ文字列内にあります。 フォームのメソッドをPOSTに設定した場合、すべてのパラメータはリクエストボディにあります。

出典:HTML 4.01規格、セクション 17.13フォーム送信


8


プログラム的な観点からは、クライアントにとってはパラメータをパッケージ化してURLに追加し、POSTを実行するのと比べて GET。 サーバー側では、投稿されたバイトの代わりにクエリ文字列からの受信パラメータを評価します。 基本的に、それは洗い物です。

利点/不利な点がある場合は、特定のクライアントプラットフォームがネットワークスタック内でPOSTおよびGETルーチンとどのように連携するか、およびWebサーバーがそれらの要求を処理する方法に問題がある可能性があります。 実装によっては、一方のアプローチの方が他方よりも効率的な場合があります。 それを知っていることがここでの決断の指針となります。

それにもかかわらず、プログラマーの観点から、私はボディのすべてのパラメータを使ったPOST、またはURLのすべてのパラメータを使ったGETのいずれかを許可し、どんなPOSTリクエストでもURLパラメータを明示的に無視します。 混乱を避けます。


4


コンテンツペイロードをPOST本文に限定したままURL上のリソースを識別するクエリ引数を持つことは、まだ非常にRESTfulである可能性があると思います。 これは、「私が送っているものは何ですか?」という考慮事項を切り離しているように見えます。対 "誰に送っているの?"


1


http://en.wikipedia.org/wiki/Representational_State_Transfer[REST]キャンプには、HTTP動詞の使用方法を標準化するために使用できるいくつかの指針となる原則があります。 あなたがしているようにRESTful APIを構築するとき、これは役に立ちます。

一言で言えば:GETは読み取り専用にする必要があります。 サーバーの状態には影響しません。 POSTはサーバー上にリソースを作成するために使用されます。 PUTはリソースを更新または作成するために使用されます。 DELETEはリソースを削除するために使用されます。

言い換えれば、あなたのAPIアクションがサーバーの状態を変更した場合、RESTはPOST / PUT / DELETEを使用することを推奨しますが、GETは使用しません。

ユーザーエージェントは通常、POSTの目的はサーバーの状態を変更することであるため、複数のPOSTを実行するのは悪いことであり、それに対して警告することを理解しています。 チェックアウト時に商品の代金を支払います、そしてあなたはたぶんそれを二度やりたくないでしょう!

あなたが好きなようによくできるGETと比較してください(べき等)。


-12


私は同意します - あなたが単にボディーではなくURLでデータを渡しているなら、それはおそらくGETリクエストを使うほうが安全です。 POST GETの概念全体に関するその他の見解については、https://stackoverflow.com/questions/262925/passing-params-in-the-url-when-using-http-post [この同様の質問]を参照してください。