5

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 サービスですが (公開されることはありません)、さまざまなネットワーク セキュリティ アプリケーション (ファイアウォール、コンテンツ フィルターなど) を介してアクセスされる可能性があり、既知の開発スタイル、標準、およびアーキテクチャに固執したいと考えています。できる限り。

4

8 に答える 8

6

I would think about "RESTful querying" as having two resources: Query and QueryResult.

You POST your Query to one end-point (e.g. "POST /queries/") and receive a CREATED Status back with the URI of your specific query (/queries/123) and a nice and RESTful hypertext body telling you the URL of your query result (e.g. /result/123 ). Then you access your query result with a GET /result/123. (Bonus points if you use hypertext to link back to /queries/123 so that the consumer of the query result can check and modify the query.

To elaborate the point I'm trying to make:

If RESTful is basically reduced to "map business entities to URIs" than the obvious question arises: "how can I query a subset of my entities"? Often the solution is "adding a query string to the 'all entities of this type'-URL" - Why else would it be called "query string"?. But it starts to feel "wrong" - as stated in the OP - if you want to have a full fledged query interface.

The reason is that with this requirement the Query becomes a full business object itself and is no longer an addendum to an resource address. It's no longer secondary but primary. It becomes important enough to become a resource in its own right - with it's own address (e.g. URL) and representation.

于 2013-09-21T08:18:03.643 に答える
3

オプション 4 を使用します。特に検索サーバーに対して、大規模な検索要求のクエリ表現を json に入れるのは困難です。その場合、URI でリソースを識別できないため、Restful スタイルには適合しません。REST はガイドラインです。シナリオが REST で実現できない場合は、問題を解決する何かを行うと思います。ここで POST を使用するのは安らかではありませんが、正しい解決策のようです。

于 2013-09-18T22:28:31.173 に答える
1

最良の方法は、検索 JSON オブジェクトをシリアル化し、それをクエリ パラメーターとして渡すことです。最新のブラウザやサーバーでは時間がかかりすぎますか? 最新のブラウザーとサーバーは、かなり大きな GET クエリ パラメーターの長さ、数千文字を処理できます。

X-Custom-Query-Parameters-JSONおそらく、オブジェクトが 8k 文字程度になる ような拡張ヘッダーです。

特定のケースでは、シリアル化された JSON オブジェクトは何文字になりますか?

文字制限に関するいくつかの関連する質問:

QueryString / GET / URL パラメータの制限は何ですか

実際の HTTP ヘッダーの長さ制限はありますか?

于 2013-09-25T03:04:54.757 に答える
1

これについてもっと考えた後、私は別の答えを出すつもりです。

JSON表現が「比較的大きい」と述べたとき、推定文字数で何を意味しますか? IE は 2,000 文字を超える URL を処理できます。クエリがそれよりも大きくなることはありますか? クエリ文字列が進むべき道だと思うからです。現在、JSONP を使用するシステムで作業しているため、クエリ文字列ですべてのデータを JSON パッケージとして渡す以外に選択肢がなく、正常に動作します。GET 動詞の使用は意味的に正しいだけでなく、URL を結果にブックマークできる機能も含まれます。ユーザーは、社内で使用する電子メールやその他の電子通信システムを介して、データ結果へのリンクを簡単に共有できます。

于 2013-09-19T14:13:36.187 に答える
0

興味深い問題です。あなたが何をしようとしているのかについての詳細はわかりませんが、1 つのリソースで適切に処理するには多すぎるのではないかと思います。リクエストの主な特徴に応じて、いくつかの異なるタイプに分割することができます。HTTPリクエストを介してSQLクエリであるべきものを公開しようとしているだけなら、混乱なく実装できる方法はないと思います。クエリ文字列に SQL クエリを渡すだけで、それを実行するための適切な方法を見つけようとするのをやめてください - それは存在しません。

于 2013-09-18T20:37:42.543 に答える