ASP.NET と IIS で実行される (多かれ少なかれ) RESTful 内部 Web サービスを設計しています。クライアントが大量のエントリのコレクションにアクセスするときに、JSON を使用して既知の方法でクエリを記述し、クエリの詳細をサーバーに渡すことができるようにしたいと考えています。問題は、サーバーに送信されるクエリが複雑になることです。集計、フィルタリング、マッピングなど、基本的に LINQ クエリ演算子でサポートされているすべてのものが含まれる場合があります。これにより、クエリを表す比較的大きな JSON オブジェクトが生成されます。
私が直面している矛盾はGET
、REST の世界ではクエリが意味的には である一方で、GET
. この問題を回避するためのいくつかのオプションを考え出しました。
オプション 1:要求の本文でクエリ オブジェクトを送信しますGET
。
GET /namespace/collection/ HTTP/1.1
Content-Length: 22
{ /* query object */ }
明らかに、これは非標準であり、一部のソフトウェアはGET
本文を持つ要求で停止する可能性があります。(さらに悪いことに、単に本文を取り除いて、本文なしでリクエストを処理すると、サーバーが正しくない結果セットを返すことになります。)
オプション 2:の代わりに非標準の HTTP 動詞 (おそらくQUERY
) を使用しGET
ます。
QUERY /namespace/collection/ HTTP/1.1
Content-Length: 22
{ /* query object */ }
これは REST パターンに正確には適合しませんが、(私には) 安全な代替手段のように思えます。なぜなら、他のソフトウェア (WebDAV を使用するものなど) は非標準の HTTP 動詞を使用して十分な成功を収めているように見えるからです。
オプション 3:クエリ オブジェクトを非標準の HTTP ヘッダーに配置します。
GET /namespace/collection/ HTTP/1.1
ProjectName-Query: { /* query object */ }
このオプションは、リクエストを として保持しますGET
が、非常に大きなオブジェクトになる可能性があるものを HTTP ヘッダーに詰め込む必要があります。一部のソフトウェアでは、HTTP ヘッダーに任意の長さの制限が設定されていることを理解しています。そのため、オブジェクトが大きくなりすぎると問題が発生する可能性があります。
オプション 4:動詞を使用してPOST
、クエリ用の代替エンドポイントを提供します。
POST /namespace/collection/query HTTP/1.1
Content-Length: 22
{ /* query object */ }
これは標準の動詞を使用し、標準のヘッダーを使用しないため、このメソッドはすべてのシナリオで機能することが保証されています。唯一の問題は、RESTful アーキテクチャーから逸脱していることです。私はこれにできる限り従おうとしています。
これらのオプションはどれも完全に正しいものではありません。私が知りたいのは、私が書いているサービスにとってどの方法が最も理にかなっているのかということです。これは内部 Web サービスですが (公開されることはありません)、さまざまなネットワーク セキュリティ アプリケーション (ファイアウォール、コンテンツ フィルターなど) を介してアクセスされる可能性があり、既知の開発スタイル、標準、およびアーキテクチャに固執したいと考えています。できる限り。