質問

検索をRESTful URLとして表す合理的な方法を探しています。

セットアップ:車とガレージの2つのモデルがあり、車をガレージに入れることができます。だから私のURLは次のようになります:

/car/xxxx
  xxx == car id
  returns car with given id

/garage/yyy
  yyy = garage id
  returns garage with given id

車は、単独で存在することができるため(/ car)、またはガレージに存在することができます。たとえば、指定されたガレージ内のすべての車を表す正しい方法は何ですか?次のようなもの:

/garage/yyy/cars     ?

ガレージyyyとzzzの車の組合はどうですか?

特定の属性を持つ車の検索を表す正しい方法は何ですか?説明:4ドアの青いセダンをすべて見せてください:

/car/search?color=blue&type=sedan&doors=4

または代わりに/ carsにする必要がありますか?

" search"の使用そこでは不適切と思われる-より良い方法/用語は何ですか?ただあるべきです:

/cars/?color=blue&type=sedan&doors=4

検索パラメーターはPATHINFOまたはQUERYSTRINGの一部ですか?

要するに、クロスモデルのREST URLデザインと検索のガイダンスを探しています。

[更新]ジャスティンの答えは好きですが、彼はマルチフィールド検索のケースをカバーしていません。

/cars/color:blue/type:sedan/doors:4

またはそのようなもの。どうやって行くの

/cars/color/blue

複数フィールドの場合

役に立ちましたか?

解決

検索には、クエリ文字列を使用します。これは完全にRESTfulです:

/cars?color=blue&type=sedan&doors=4

通常のクエリ文字列の利点は、標準で広く理解されており、form-getから生成できることです。

他のヒント

RESTfulプリティURLデザインは、構造(ディレクトリのような構造、日付:articles / 2005/5/13、オブジェクトとその属性など)に基づいてリソースを表示することです。スラッシュ / は階層構造を示し、代わりに -id を使用します。

階層構造

私は個人的に好みます:

/garage-id/cars/car-id
/cars/car-id   #for cars not in garages

ユーザーが / car-id 部分を削除すると、直感的に cars プレビューが表示されます。ユーザーは、ツリーのどこにいるのか、何を見ているのかを正確に知っています。彼は最初の外観から、ガレージと車が関係していることを知っています。 / car-id は、 / car / id とは異なり、一緒に属していることも示します。

検索中

検索クエリはそのままで問題ありません、あなたの好みだけが考慮されます。検索に参加するときに面白い部分があります(以下を参照)。

/cars?color=blue;type=sedan   #most prefered by me
/cars;color-blue+doors-4+type-sedan   #looks good when using car-id
/cars?color=blue&doors=4&type=sedan   #I don't recommend using &*

または基本的には、上記で説明したようなスラッシュではないもの。
式: / cars [?;] color [=-:] blue [、; +&] 、* & 記号を使用しませんが一見するとテキストから認識できません。

  

** JSONオブジェクトをURIで渡すことはRESTfulであることをご存知ですか? **

オプションのリスト

/cars?color=black,blue,red;doors=3,5;type=sedan   #most prefered by me
/cars?color:black:blue:red;doors:3:5;type:sedan
/cars?color(black,blue,red);doors(3,5);type(sedan)   #does not look bad at all
/cars?color:(black,blue,red);doors:(3,5);type:sedan   #little difference

可能な機能?

検索文字列の否定(!)
車を検索するが、ではない および
?color =!black、!red
color :(!black、!red)

参加検索
ガレージID 1..20 3 ドアがある red または blue または black の車を検索しますem>または 101..103 または 999 ではない 5 / garage [id = 1-20,101-103,999、!5] / cars [color = red、blue、black; doors = 3]
その後、より複雑な検索クエリを作成できます。 ( CSS3属性の一致を見て、部分文字列の一致のアイデアを見つけてください。たとえば、&quotを含むユーザーの検索; bar" user * = bar

結論

とにかく、これはあなたにとって最も重要な部分かもしれません。なぜなら、あなたが好きなようにできるからです。 RESTful URIは、たとえばディレクトリのような / directory / file / collection / node / item 、日付 / articles / {year} / {month} / {day} ..そして、最後のセグメントのいずれかを省略すると、何が得られるかすぐにわかります。

したがって、これらのすべての文字は、エンコードされないことが許可されています

  • 未予約: a-zA-Z0-9 _.-〜
  • 予約済み:; /?:@ =& $ -_。+!* '()、
  • 安全でない*:<>"#%{} | \ ^〜[] `

*安全ではない理由とエンコードする必要がある理由: RFC 1738 2.2を参照

RFC 3986 2.2を参照
以前に言ったことにも関わらず、ここにデリミターの一般的な区別があります。つまり、一部の"" は他のものよりも重要です。

  • 汎用デリミター::/?#[] @
  • サブデリメーター:!$& '()* +、; =

その他の読み物:
階層: 2.3を参照 1.2.3を参照
URLパスパラメーターの構文
CSS3属性の一致
IBM:RESTful Webサービス-basi

パスにパラメーターがあることにはいくつかの利点がありますが、IMOにはいくつかの重要な要素があります。

  • 検索クエリに必要なすべての文字がURLで許可されているわけではありません。ほとんどの句読点とUnicode文字は、クエリ文字列パラメーターとしてURLエンコードする必要があります。私は同じ問題に取り組んでいます。 URLでXPathを使用したいのですが、すべてのXPath構文がURIパスと互換性があるわけではありません。したがって、単純なパスの場合、ドライバーのドアXMLドキュメントで「 combination 」要素を見つけるには、 / cars / doors / driver / lock / combination が適切です。しかし、 / car / doors [id = 'driver'およびlock / combination = '1234'] はそれほどフレンドリーではありません。

  • 属性の1つに基づいてリソースをフィルタリングすることと、リソースを指定することには違いがあります。

    たとえば、

    / cars / colors は、すべての車のすべての色のリストを返します(返されるリソースは色オブジェクトのコレクションです)

    / cars / colors / red、blue、green は、車のコレクションではなく、赤、青、または緑の色オブジェクトのリストを返します。

    車を返すには、パスは次のようになります

    / cars?color = red、blue、green または / cars / search?color = red、blue、green

  • 名前/値のペアはパスの残りの部分(名前/値のペアではない)から分離されていないため、パスのパラメーターは読みにくくなります。

最後のコメント。 / garage / yyy / cars (常に複数形)よりも / garage / yyy / cars (おそらく元の回答のタイプミスだった)を好む単数形と複数形の間。 「s」が追加された単語の場合、変更はそれほど悪くありませんが、 / person / yyy / friends / people / yyy に変更するのは面倒です。

Justinの答えはおそらく進むべき道です。ただし、アプリケーションによっては、特定の検索を、名前付き保存検索をサポートする場合など、それ自体がリソースとして考えるのが理にかなっている場合があります。

/search/{searchQuery}

または

/search/{savedSearchName}

これはRESTではありません。 API内のリソースのURIを定義することはできません。リソースナビゲーションはハイパーテキスト駆動である必要があります。きれいなURIと大量のカップリングが必要な場合は問題ありませんが、RESTfulアーキテクチャの制約に直接違反するため、RESTとは呼ばないでください。

発明者による記事をご覧くださいRESTの。

検索を実装するには、2つのアプローチを使用します。

1)最も単純なケース、関連する要素のクエリ、およびナビゲーション。

    /cars?q.garage.id.eq=1

これは、ガレージIDが1の車を照会することを意味します。

より複雑な検索を作成することもできます:

    /cars?q.garage.street.eq=FirstStreet&q.color.ne=red&offset=300&max=100

FirstStreetのすべてのガレージにある車のうち、赤ではない車(3ページ目、ページあたり100要素)。

2)複雑なクエリは、作成されて回復可能な通常のリソースと見なされます。

    POST /searches  => Create
    GET  /searches/1  => Recover search
    GET  /searches/1?offset=300&max=100  => pagination in search

検索作成のPOST本文は次のとおりです。

    {  
       "$class":"test.Car",
       "$q":{
          "$eq" : { "color" : "red" },
          "garage" : {
             "$ne" : { "street" : "FirstStreet" }
          }
       }
    }

Grails(基準DSL)に基づいています: http: //grails.org/doc/2.4.3/ref/Domain%20Classes/createCriteria.html

Justinの応答は気に入っていますが、検索よりもフィルターをより正確に表していると感じています。 camで始まる名前の車について知りたい場合はどうすればよいですか?

私の見方では、特定のリソースを処理する方法に組み込むことができます。
/ cars / cam *

または、単にフィルターに追加することもできます。
/ cars / doors / 4 / name / cam * / colors / red、blue、green

個人的には後者を好むが、私は決してRESTの専門家ではない(2週間ほど前に初めて聞いたことがある...)

RESTfulは、URLの/ cars / searchで動詞を使用することをお勧めしません。 APIをフィルタリング/検索/ページ分割する正しい方法は、クエリパラメータを使用することです。ただし、規範を破る必要がある場合があります。たとえば、複数のリソースを検索する場合は、/ search?q = query

のようなものを使用する必要があります

http://saipraveenblog.wordpress .com / 2014/09/29 / rest-api-best-practices / RESTful APIを設計するためのベストプラクティスを理解する

さらに、私もお勧めします:

/cars/search/all{?color,model,year}
/cars/search/by-parameters{?color,model,year}
/cars/search/by-vendor{?vendor}

ここでは、 Search Cars リソースの子リソースと見なされます。

ここには、あなたのケースに適したオプションがたくさんあります。それでも、POST本体の使用を検討する必要があります。

クエリ文字列は例に最適ですが、もっと複雑なものがある場合、たとえばアイテムまたはブール条件の任意の長いリスト、クライアントがPOSTを介して送信するドキュメントとして投稿を定義することができます。

これにより、検索のより柔軟な説明が可能になり、サーバーURLの長さ制限が回避されます。

私のアドバイスはこれでしょう:

/garages
  Returns list of garages (think JSON array here)
/garages/yyy
  Returns specific garage
/garage/yyy/cars
  Returns list of cars in garage
/garages/cars
  Returns list of all cars in all garages (may not be practical of course)
/cars
  Returns list of all cars
/cars/xxx
  Returns specific car
/cars/colors
  Returns lists of all posible colors for cars
/cars/colors/red,blue,green
  Returns list of cars of the specific colors (yes commas are allowed :) )

編集:

/cars/colors/red,blue,green/doors/2
  Returns list of all red,blue, and green cars with 2 doors.
/cars/type/hatchback,coupe/colors/red,blue,green/
  Same idea as the above but a lil more intuitive.
/cars/colors/red,blue,green/doors/two-door,four-door
  All cars that are red, blue, green and have either two or four doors.

うまくいけば、アイデアが得られます。基本的に、Rest APIは簡単に検出でき、データを参照できる必要があります。クエリ文字列ではなくURLを使用することのもう1つの利点は、Webサーバー上に存在するネイティブのキャッシュメカニズムをHTTPトラフィック用に利用できることです。

RESTのクエリ文字列の悪について説明するページへのリンク: http://web.archive.org/web/20070815111413/http://rest.blueoxen.net/cgi-bin/wiki.pl?QueryStringsConsideredHarmful

通常のページが機能していなかったため、Googleのキャッシュを使用しました。ここにもそのリンクがあります。 http://rest.blueoxen.net/cgi-bin/wiki.pl? QueryStringsConsideredHarmful

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top