HTTP GETクエリ文字列の長さの制限に対処し、それでもRESTfulにしたい場合はどうすればよいですか?


84

http://www.boutell.com/newfaq/misc/urllength.htmlに記載されているように、HTTPクエリ文字列の長さには制限があります。クライアント(Firefox、IE、...)、サーバー(Apache、IIS、...)、またはネットワーク機器(適用可能なファイアウォール、...)によって制限される可能性があります。

今日、私は検索フォームでこの問題に直面しています。多くのフィールドを含む検索フォームを開発しました。このフォームはGETリクエストとしてサーバーに送信されるため、結果のページをブックマークできます。

クエリ文字列の長さが1100バイトになるほど多くのフィールドがあり、1024バイトを超えるHTTPGETリクエストをドロップするファイアウォールがあります。システム管理者は、制限がないように、代わりにPOSTを使用することをお勧めします。

確かに、POSTは機能しますが、検索はPOSTではなくGETとして実際に感じます。したがって、フィールド名を確認してクエリ文字列が長すぎないことを確認し、長すぎない場合は実用的でPOSTを使用すると思います。

しかし、RESTfulサービスの設計に欠陥はありますか?GETリクエストの長さが制限されている場合、大きなオブジェクトをRESTful Webサービスに送信するにはどうすればよいですか?たとえば、ファイルに基づいて計算を行うプログラムがあり、次のようなRESTfulWebサービスを提供したい場合:http://compute.com?content=<base64 file>。クエリ文字列の長さが無制限ではないため、これは機能しません。

私は少し戸惑っています...


2
あなたの文脈の観点から、安らかなとはどういう意味ですか?または言い換えると、GETが安らかで、POSTが安らかでないのはなぜですか?GETは単純な文字列連結を使用して構築できるためですか?クエリの長​​さの制限は、高速で動作することを目的としたアプリでの動的なメモリ割り当てを回避することです。
khachik 2010年

5
検索を行うときは、何かを作成、削除、更新するのではなく、データを取得するだけなので、POST、DELETE、またはPUTを使用せず、GETを使用する必要があります。これが私がRESTを理解した方法ですが、私はそれについて誤解されているかもしれません
cbliard 2010年

検索結果は時間の経過とともに変化する可能性があるため、GETは検索には適していません。多くの場合、WebインフラストラクチャではGETリクエストのキャッシュが可能です。GETを使用すると、検索で古い古い結果が得られるリスクがあります。以下に推奨するように、POSTがその方法です。
occulus 2012年

15
すべてが時間の経過とともに変化します(en.wikipedia.org/wiki/Impermanence)。これが宇宙の性質です...しかし、「検索アクション」は結果を変更しないため、検索にはGETを使用する必要があります
Luxspes 2012年

回答:


51

あなたの説明に基づいて、私見あなたはPOSTを使うべきです。POSTは、サーバーにデータを配置し、場合によっては回答を取得するためのものです。あなたの場合、あなたは検索を行い(サーバーにクエリを送信し)、その検索の結果を取得します(クエリ結果を取得します)。

GETの定義は、既存のリソースを取得するために使用する必要があることを示しています。定義上、POSTは新しいリソースを作成することです。これはまさにあなたがしていることです:サーバー上にリソースを作成し、それを取得します!検索結果を保存しなくても、サーバー上にオブジェクトを作成して取得しました。PeterMmmが以前に言ったように、これはPOST(クエリ結果の作成と保存)で実行し、GETを使用してクエリを取得できますが、POSTのみを実行して結果を取得する方が現実的です。

お役に立てれば!:)


2
そうです、検索は揮発性の新しく計算されたリソースであるため、POSTと見なすことができます。しかし、POSTとGETの境界を確認するのにまだ問題があります。図書館のすべてのサイエンスフィクションの本を検索したい場合は、既存のリソースのコレクションを取得するので、GETを使用したくなりますが、検索自体が新しいリソースであるため、POSTとして表示することを提案します。したがって、GETのクエリ文字列は、データ表現を変更するためにのみ使用する必要があり、データをフィルタリングするためには使用しないでください。私は正しいですか?
cbliard 2010年

8
POSTは検索には使用しないでください。GETを使用する必要があります。この方法で、結果のURLと結果を共有およびキャッシュでき、インターネットのRESTfulアーキテクチャをより有効に活用できます
Luxspes 2012年

37
この答えは、言葉で遊んでみようとしているように聞こえます。そのロジックにより、すべてをPOSTリクエストとして作成し、それでもRESTfulにすることができます。
supertonsky 2014

9
この答えは、ある弁護士が私に話しかけているようです:-)質問は、実際には「GETケースがあります、わかりました。しかし、クエリ文字列が許可された長さを超えています。どのように処理しますか」です。この答えに反対票を投じる。
G. Stoynev 2015

2
そのロジックに従っている場合、すべてのリクエストはリソースを作成して取得しています。
アレックス

66

HTTP仕様では、計算のためにデータをリソースに送信するときにPOSTを使用することを実際に推奨しています

検索は、リソース自体ではなく、計算のように見えます。それでも検索結果をリソースにしたい場合は、トークンを作成してその特定の検索結果を識別し、ユーザーエージェントをそのリソースにリダイレクトすることができます。

その後、しばらくすると検索結果トークンを削除できます。

POST /search
query=something&category=c1&category=c2&...

201 Created
Location: /search/01543164876

その後

GET /search/01543164876

200 Ok
... your results here...

このように、ブラウザとプロキシは引き続き検索結果をキャッシュできますが、POSTを使用してクエリパラメータを送信しています。

編集

明確に01543164876するために、ここでは検索を表すリソースの一意のIDを表します。これらの2つのリクエストは、基本的に、これらの条件で新しい検索オブジェクトを作成し、作成された検索オブジェクトに関連付けられた結果を取得することを意味します。

このIDは、新しいリクエストごとに生成される一意のIDにすることができます。これは、サーバーが「検索」オブジェクトをリークすることを意味し、キャッシュ戦略を使用してオブジェクトを定期的にクリーンアップする必要があります。

または、ユーザーが尋ねた検索を実際に表すすべての検索条件のハッシュにすることもできます。これにより、IDを再利用できます。これは、検索を再作成すると、すでにキャッシュされている(またはされていない)既存のIDが返されるためです。


これは、クエリのブックマークに関するOP要件にどのように対処しますか?
ルバーブ2014年

2
@Rhubarbは、特定の検索用のリソースを作成することで、明確に対処します。
maulik13 2014

3
これにより、結果が遅くなります。投稿を実行してから、GETを実行します。検索をフェッチするために、少なくとも300ミリ秒が追加されます。
jaxxbo 2015年

ソースへのリンクが切れています
Emobe 2017年

私は混乱しています、サーバーはPOSTとGETの間に何をしますか?サーバーに検索データをキャッシュし、GETリクエストが届くのを待つだけですか?これを行うには、一意のIDを使用する必要があるため、キャッシュを取得できます。あなたの答えは素晴らしいですが、確かに完全ではありません。また、キャッシュを使用すると、ステートレスが少なくなります。
アレクサンダーミルズ

5

RESTは物事を行う方法であり、プロトコルではありません。それが本当にGETであるときにPOSTを嫌う場合でも、それは機能します。

クエリをPOSTすることを検討するよりも、GET、POSTなどの「標準」定義を維持する必要がある場合、そのクエリはクエリIDを使用してサーバーに保存され、後でGET byidを使用してクエリを要求します。


4

あなたの例に関して:http://compute.com?content={base64file}、あなたが計算される「何か」をアップロードしているので、私はPOSTを使用します。私にとって、この「何か」は、単純なパラメーターとしてのリソースのように感じます。

これとは対照的に、通常の検索では、GETとパラメーターを使い始めます。これにより、APIクライアントがAPIをテストして操作することが非常に簡単になります。読み取り専用アクセス(ほとんどの場合、トラフィックの大部分)をできるだけ単純にします。

しかし、大きなクエリ文字列のジレンマは、GETの有効な制限です。ここでは、この制限に達しない限り、GETとurl-paramsを使用して実用的に説明します。これは、検索ケースの98%で機能します。この制限に達した場合にのみ動作し、ペイロード付きのPOST(mime-type付きContent-Type: application/x-www-form-urlencoded)も導入します。

もっと実際の例がありますか?


計算は実際の例でした。検索については、複数のセルポイントの取引を検索できるようにしたいので、新しいブラウザウィンドウを開いてセルポイントを選択します。また、検証するときに、検索フォームの非表示パラメーターを変更して、選択したセルポイントを設定します。それらが本当に多い場合、結果の検索要求には非常に長いクエリ文字列が含まれます。
cbliard 2010年

4

GETに関する混乱は、ブラウザーの制限です。A2AまたはP2Pアプリケーション用のRESTfulインターフェースを作成している場合、GETの長さに制限はありません。

さて、ブラウザを使用してRESTfulインターフェイスを表示したい場合(開発/デバッグ中)、この制限に遭遇しますが、これを回避するためのツールがあります。


6
「GETはブラウザの制限です」-これはサーバーの制限でもあります。すべてのWebサーバーが制限を適用していることがわかります。また、CDNがある場合は、制限を適用することもあります。他のツールを使用してリクエストを実行しても、サーバーの制限を回避することはできません。
コートニーマイル

0

これは簡単なものです。POSTを使用します。HTTPはGETのURLの長さに制限を課しませんが、サーバーは制限を課します。実用的であり、POSTでそれを回避します。

GET本体(許可されている)を使用することもできますが、これは正しい使用法ではなく、サーバーの問題が発生する可能性があるという点で二重の問題です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.