web-dev-qa-db-ja.com

複雑なRESTful検索メソッドを実行する適切な方法は何ですか?

REST原則に従って、いくつかの基準を使用して検索を行い、結果をクライアントに返すAPIのGETメソッドを作成します。問題は、基準が最大14パラメータ、それらの1つは複雑なオブジェクトのリストなので、...

  • これらの複雑なオブジェクトをURLパラメータとの間でエンコード/デコードできるかどうかさえわかりません。

  • URLが到達するまでの時間を計算していませんが、URLが十分に大きく、URLの長さの制限に達する可能性があると確信していますか?

また、検索では結果が「リアルタイム」で表示されるはずです。つまり、ユーザーが検索フォームから何かを変更するたびに、「検索」ボタンを押すことなく新しい結果を表示できるはずです。

これらの点を明確にしてもらえますか、そして多くのパラメーターを備えた安らかな検索メソッドを作成するためのアドバイスは何ですか?

49
anat0lius

私の回答を読む前に、@ Neilに同意したと申し上げます。私たちは戦いを選ばなければなりません。私たちは通常、最善を尽くしたいのですが、時には議論の余地が少なく、意志に反して決定を下さなければなりません。

とにかく、ニールの答えでは、もう1つ欠けています。 ドキュメント。開発者がPOSTへのリクエスト/searchは安全です。

それは言った。

1. GETチャンスを与える

最初にGETオプションを検討してください。この質問をチェックしてください RLの最大長 。最長のクエリ文字列が2000文字より長いかどうかを評価します。そうでない場合で、期待していない場合は、GETを使用してください。醜く見えるかもしれませんが、メソッドのセマンティクス(べき等性、安全性、キャッシング)から派生したすべての利点があります。そしてブックマーク。

1.1クエリ文字列をエンコードしてみる

たとえば、base 64の場合 JavaScriptでもbase 64エンコーディングをサポートしています

これがどのように機能するかです:

  1. すべてのフィルターを使用してJSONを作成し、正規化します。
  2. 文字列に解析します
  3. エンコードする
  4. エンコードされたJSONをリクエストパラメータ(/search?q=SGVsbG8gV29ybGQh....)。
  5. サーバー側で、qをデコードします。
  6. JSON文字列を逆シリアル化する

以前は、可能な限り長いJSON文字列を作成し、エンコードして長さを取得していました。エンコードされた文字列がURLに収まるかどうかを評価します。テストするために、次のスニペットを Fiddle.js に実装しました。 (私はそれがまだうまくいくことを願っています)1

Base 64エンコードは確定的で可逆的であるため、衝突する可能性はありません。

エンコードされたクエリを使用して、検索をDBに保存したり、URLをブックマークしたり、リンクを共有したりすることもできます。もちろん、文字列(私が嫌いなもの)をエスケープ/エスケープ解除する必要はありません。

1.2エイリアスで試す

これを読む ブログ 設計方法についてREST API、もう1つの代替案を思い出しました。一般的なクエリのエイリアス

これらは次の理由で興味深いと思います

  • クエリ文字列の長さを短くしてください。 APIをよりクリーンで使いやすいものにします

    GET/tickets /?status = closed&closedAt = xxxvsGET/tickets/recently-closed /

  • より多くのエイリアスまたはより多くのリクエストパラメータと組み合わせることができます。

    GET/tickets /?status = closed&closedAt = xxx&within = 30minvsGET/tickets/recently-closed /?within = 30min

  • エンコードされたクエリ文字列とエイリアスを組み合わせることができます

    GET/tickets /?status = closed&closedAt = xxx&within = 30minvsGET/tickets/recently-closed /?q = SGVsbG8g ...


1:JSONを使用しましたが、サーバー側でこれらを逆シリアル化できるようになるとすぐに、他の形式を使用することができます。

63
Laiv

ハンマーさえあれば、すべてが釘のように見えます。ここでの問題は、検索ページをRESTfulなページに変換しようとしていることであり、これはRESTfulな設計が解決するための一般的なパターンとは思えない。

POSTリクエストを使用して、ユーザーが提供するパラメーターを指定して、バックエンドから必要な情報を取得します。検索を実行する以外は何もする必要がないため、このページから挿入する必要がある可能性があります。URLの末尾に/ searchを追加するだけで、-= RESTfulである/ usersページと競合するリスクを回避できます。

14
Neil

それは、あなたのAPIモデルが何であるか、または動詞であるかに完全に依存します。

APIがnoneの場合、次のようにオブジェクトのリストを取得できます。

GET: /api/v1/objects

この場合、リクエストパラメータとしてデータを送信する必要があります。したがって、パラメーターをKey-Valueのフラットリストとして説明する必要があります。

GET: /api/v1/objects

key1 : val1
key2.key1 : val 21
key2.key2 : val 22
....

一部のプラットフォームはカスタムパラメータリゾルバ(Spring MVCなど)をサポートしており、パラメータをオブジェクトに変換できます。

0
Mostafa