これらの問題に直面するたびに、「従来の Web ページを作成しているとしたら、これをユーザーにどのように提示するか」と自問します。簡単な答えは、この種のオプションを 1 つのページに表示しないということです。インターフェースが複雑すぎます。しかし、私ができることは、ユーザーが多数のページにわたってますます複雑なクエリを作成できるようにするインターフェイスを提供することです。
HATEOAS 制約は、応答にハイパーメディア コントロール (リンクとフォーム) を含める必要があることを指定します。/cars
で、検索オプション付きのページ分割された車のコレクションがあるとしましょう。取得すると、/cars
次のようなものが返されます (ところで、ここではカスタム メディア タイプを使用していますが、フォームとリンクはかなり明白なはずです。そうでないかどうかを確認してください):
<cars href="/cars">
<car href="/cars/alpha">...</car>
<car href="/cars/beta">...</car>
<car href="/cars/gamma">...</car>
<car href="/cars/delta">...</car>
...
<next href="/cars?page=2"/>
<search-color href="/cars" method="GET">
<color type="string" cardinality="required"/>
<color-match type="enumeration" cardinality="optional" default="substring">
<option name="exact"/>
<option name="substring"/>
<option name="regexp"/>
</color-match>
<color-logic type="enumeration" cardinality="optional" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</color-logic>
</search>
<search-doors href="/cars" method="GET">
<doors type="integer" cardinality="required"/>
<door-logic type="enumeration" cardinality="required" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</door-logic>
</search>
</cars>
たとえば、白い車を検索すると、GET を実行する/cars?color=white
と、次のような結果が返される可能性があります。
<cars href="/cars?color=white">
<car href="/cars/beta">...</car>
<car href="/cars/delta">...</car>
...
<next href="/cars?color=white&page=2"/>
<search-color href="/cars?color=white" method="GET">
<color2 type="string" cardinality="required"/>
<color2-match type="enumeration" cardinality="optional" default="substring">
<option name="exact"/>
<option name="substring"/>
<option name="regexp"/>
</color2-match>
<color2-logic type="enumeration" cardinality="optional" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</color2-logic>
</search>
<search-doors href="/cars?color=white" method="GET">
<doors type="integer" cardinality="required"/>
<door-logic type="enumeration" cardinality="required" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</door-logic>
</search>
</cars>
この結果から、クエリを絞り込みましょう。したがって、「オフホワイト」の車ではなく白い車が必要だと言うだけで、GET '/cars?color=white&color2=off-white&color2-logic=not' が返される可能性があります。
<cars href="/cars?color=white&color2=off-white&color2-logic=not">
<car href="/cars/beta">...</car>
<car href="/cars/delta">...</car>
...
<next href="/cars?color=white&color2=off-white&color2-logic=not&page=2"/>
<search-color href="/cars?color=white&color2=off-white&color2-logic=not" method="GET">
<color3 type="string" cardinality="required"/>
<color3-match type="enumeration" cardinality="optional" default="substring">
<option name="exact"/>
<option name="substring"/>
<option name="regexp"/>
</color3-match>
<color3-logic type="enumeration" cardinality="optional" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</color3-logic>
</search>
<search-doors href="/cars?color=white&color2=off-white&color2-logic=not" method="GET">
<doors type="integer" cardinality="required"/>
<door-logic type="enumeration" cardinality="required" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</door-logic>
</search>
</cars>
その後、クエリをさらに絞り込むことができますが、ポイントは、途中の各ステップで、ハイパーメディア コントロールが可能なことを教えてくれることです。
ここで、車の検索オプションについて考えてみると、色、ドア、メーカー、およびモデルは無制限ではないため、列挙を提供することでオプションをより明確にすることができます。例えば
<cars href="/cars">
...
<search-doors href="/cars" method="GET">
<doors type="enumeration" cardinality="required">
<option name="2"/>
<option name="3"/>
<option name="4"/>
<option name="5"/>
</doors>
<door-logic type="enumeration" cardinality="required" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</door-logic>
</search>
</cars>
ただし、私たちが持っている唯一の白い車は 2 ドアと 4 ドアかもしれません。その場合、GETing/cars?color=white
は私たちに与えるかもしれません
<cars href="/cars?color=white">
...
<search-doors href="/cars?color=white" method="GET">
<doors type="enumeration" cardinality="required">
<option name="2"/>
<option name="4"/>
</doors>
<door-logic type="enumeration" cardinality="required" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</door-logic>
</search>
</cars>
同様に、色を絞り込むと、それらのオプションがほんのわずかであることがわかる場合があります。その場合、文字列検索の提供から列挙型検索の提供に切り替えることができます。例えば、GETing/cars?color=white
は私たちに与えるかもしれません
<cars href="/cars?color=white">
...
<search-color href="/cars?color=white" method="GET">
<color2 type="enumeration" cardinality="required">
<option name="white"/>
<option name="off-white"/>
<option name="blue with white racing stripes"/>
</color2>
<color2-logic type="enumeration" cardinality="optional" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</color2-logic>
</search>
...
</cars>
他の検索カテゴリについても同じことができます。たとえば、最初はすべてのメーカーを列挙したくないので、何らかのテキスト検索を提供します。コレクションが洗練され、選択できるモデルがわずかしかなくなったら、列挙を提供することは理にかなっています。同じロジックが他のコレクションにも適用されます。たとえば、世界のすべての都市を列挙する必要はありませんが、地域を 10 程度の都市に絞り込むと、それらを列挙することは非常に役立ちます。
あなたのためにこれを行うライブラリはありますか?私が知っているものはありません。私が見たほとんどのものは、ハイパーメディア コントロールさえサポートしていません (つまり、リンクとフォームを自分で追加する必要があります)。使えるパターンはありますか?はい、上記はこの種の問題を解決するための有効なパターンだと思います。