web-dev-qa-db-ja.com

クエリ文字列またはリクエスト本文にデータがある安らかなURL?

クエリ文字列内のREST URLとリクエストの本文のデータを渡すための経験則は何ですか?

すなわち、あなたはホッケー選手を追加するサービスを作成しています。あなたが行くことができます:

PUT /players 
{ "name": Gretzky }

または

PUT /players?name=Gretzky

大量のデータを渡す場合、URLの長さに制限があるため、オプション#1を使用する必要があります。しかし、これ以外に、クエリ文字列を使用してデータを渡すだけではどうですか?


更新:オプション#2をブラウザーでテストできるというコメントを削除しました。ブラウザでGET-sしか実行できないことに気づきました。

33
Marcus Leon

HTTPのPUTの定義に基づいて、最初の要求は、プレーヤーのリストを、プレーヤー名を1つだけ含む新しいリストで上書きすることです。プレーヤーのリストに追加されていません。

2番目のオプションは、実際にはあまり意味がありません。体なしでPUTを行うことは、PUTの意味と実際には一致しません。

POSTの標準定義の1つが既存のリソースに追加することであることを考慮すると、なぜそうしないのかわかりません

POST /players 
{ "name": Gretzky }

すべてのプレイヤー名が一意になると確信している場合は、次のようにPUTを使用できます。

PUT /player/Gretzky
{ "name": Gretzky }

HTTPでRESTを実行することにした場合、RFC2616で定義されている方法でHTTPを使用することに同意します。これが統一されたインターフェイス制約の意味です。 REST URLとして、JavaScriptなしではブラウザでPUTを実行できないため、ブラウザでいずれのオプションもテストできません。

31
Darrel Miller

オプション#1は問題ありませんが、おそらく過剰です。 オプション#1は、=等ではないため、notで問題ありません。

オプション#2は[〜#〜] bad [〜#〜]アイデアです。それはPUTの誤用です。 PUTは主に、リクエストデータのペイロードが不透明なデータブロック(通常は大規模または階層的)である場合に使用する必要があります。小さい非階層ペイロードは、POSTとしてより意味があります。

また、クエリパラメータを使用して状態を変更しないようにしてください。 GETリクエストでない場合、技術的に危険なことは何もありませんが、実際にはRESTfulではありません。

この場合、あなたがすべきことは:

POST /players HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 12

name=Gretsky

これにより、201 Created応答が返されます。 (これには例外があります。リソースをすぐに作成せず、後で拒否される可能性がある場合は、代わりに202 Acceptedを使用してください。)

REST POSTとGETよりも多くのHTTPを使用するWebサービスを作成し、GETは、afterHTTP仕様 を読んでください(これはvery便利な読み取りです。)すべての決定を行うフレームワークを使用している場合、このルールは少し緩いです。あなたのために。

3
Bob Aman

REST操作についての私の理解は、URLがリソースを一意に識別し、リクエストの本文にリソースの表現が含まれているということです。それを考えると、どちらのオプションが本当にRESTfulかどうかは疑問です.

最初は、リソースの名前が「Players」であり、そのリソースに対するGETがプレーヤーのリストを返すと仮定します(そのGETが他のリソースURLを返すかどうかの質問には入らないでしょう...リソースデータを取得するための個別のリクエストを使用する必要があります)。

2つ目は、要求本文に「Gretsky」という名前のキーが付けられた情報が含まれていると仮定した場合です。ただし、外部でキーを生成する必要があります。

2
kdgregory