460

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

セットアップ: Cars と Garages の 2 つのモデルがあり、Cars は Garages に配置できます。したがって、私のURLは次のようになります。

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

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

Car は単独で存在することも (つまり /car)、ガレージに存在することもあります。たとえば、特定のガレージにあるすべての車を表す正しい方法は何ですか? 何かのようなもの:

/garage/yyy/cars     ?

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

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

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

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

「検索」の使用は不適切に思えます - より良い方法/用語は何ですか? それはちょうどあるべきですか:

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

検索パラメータを PATHINFO または QUERYSTRING の一部にする必要がありますか?

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

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

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

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

/cars/color/blue

複数フィールドの場合に?

4

12 に答える 12

467

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

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

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

于 2009-07-04T07:13:55.980 に答える
136

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

#階層構造# 個人的に好きなのは:

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

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

#Searching# searchquery はそのままでOKです。あなたの好み、考慮すべきことだけがあります。おもしろいのは、検索を結合するときです (以下を参照)。

/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[,;+&], * ただし、&一見しただけではテキストから認識できないため、記号は使用しません。

** URI での JSON オブジェクトの受け渡しが 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または101..103または9995ではない3 つのドアを持つ、または黒の車を
検索し ます。その後、より複雑な検索クエリを作成できます。(部分文字列の一致のアイデアについては、 CSS3 属性の一致を参照してください。たとえば、 "bar" を含むユーザーを検索します。) /garage[id=1-20,101-103,999,!5]/cars[color=red,blue,black;doors=3]
user*=bar

#結論# とにかく、これはあなたにとって最も重要な部分かもしれません。結局のところ、好きなようにできるからです。RESTful/directory/file URI は、ディレクトリのような, /collection/node/item, 日付など、簡単に理解できる構造を表していることを覚えておいてください/articles/{year}/{month}/{day}..そして最後のセグメントのいずれかを省略すると、何が得られるかがすぐにわかります。

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

  • unreserved:a-zA-Z0-9_.-~
    通常、エンコードされている場合とされていない場合の両方が許可されます。両方の使用は同等です。
  • 特殊文字:$-_.+!*'(),
  • 予約済み:;/?:@=&
    それらが表す目的のためにエンコードされずに使用される場合があります。それ以外の場合は、エンコードする必要があります。
  • 安全でない:<>"#%{}|^~[]`
    安全でない理由と、エンコードする必要がある理由: RFC 1738 2.2 を参照

その他の文字クラスについては、 RFC 1738#page-20も参照してください。

RFC 3986 2.2 を参照
してください 。以前に述べたことにもかかわらず、ここではデリミタの一般的な違いを示します。これは、一部のデリメータが他よりも「重要」であることを意味します。

  • 一般的な区切り記号::/?#[]@
  • サブ区切り:!$&'()*+,;=

詳細情報:
階層: 2.3参照、1.2.3を参照
url パス パラメーターの構文
CSS3 属性
の一致 IBM: RESTful Web サービス - 基本
注: RFC 1738 は RFC 3986 によって更新されました

于 2013-03-15T13:10:17.863 に答える
37

パスにパラメーターを含めることにはいくつかの利点がありますが、IMO では、それを上回る要因がいくつかあります。

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

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

    たとえば、

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

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

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

    /cars?color=red,blue,greenまた/cars/search?color=red,blue,green

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

最後のコメント。単数形と複数形の間のパスの変更を回避するため、(おそらく元の回答のタイプミスだった可能性があります)よりも/garages/yyy/cars(常に複数形)を好みます。/garage/yyy/cars's' がついた単語は、変化はそれほど悪くありませんが、変更/person/yyy/friendsするの/people/yyyは面倒に思えます。

于 2009-05-29T15:48:13.683 に答える
36

ピーターの答えを拡張するには、検索をファーストクラスのリソースにすることができます。

POST    /searches          # create a new search
GET     /searches          # list all searches (admin)
GET     /searches/{id}     # show the results of a previously-run search
DELETE  /searches/{id}     # delete a search (admin)

検索リソースには、色、モデルの作成、ガレージのステータスなどのフィールドがあり、XML、JSON、またはその他の形式で指定できます。Car and Garage リソースと同様に、認証に基づいて検索へのアクセスを制限できます。同じ検索を頻繁に実行するユーザーは、それらをプロファイルに保存して、再作成する必要がないようにすることができます。URL は十分に短いため、多くの場合、電子メールで簡単に取引できます。これらの保存された検索は、カスタム RSS フィードなどの基礎となることができます。

検索をリソースと考えると、検索を使用する可能性はたくさんあります。

このアイデアは、このRailscastで詳しく説明されています。

于 2009-05-29T16:03:41.923 に答える
11

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

/search/{searchQuery}

また

/search/{savedSearchName}
于 2008-10-16T10:52:48.443 に答える
8

検索の実装には 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 ページ目、1 ページあたり 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

于 2014-10-10T14:23:06.557 に答える
4

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

REST の発明者によるこの記事を参照してください。

于 2009-07-20T18:52:20.833 に答える
2

RESTful は、URL の /cars/search で動詞を使用することを推奨していません。API をフィルタリング/検索/ページ分割する正しい方法は、クエリ パラメータを使用することです。ただし、標準を破らなければならない場合もあります。たとえば、複数のリソースを検索する場合は、 /search?q=query のようなものを使用する必要があります

http://saipraveenblog.wordpress.com/2014/09/29/rest-api-best-practices/にアクセスして、RESTful API を設計するためのベスト プラクティスを理解することができます。

于 2014-10-06T06:53:25.610 に答える
-4

私のアドバイスは次のとおりです。

/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 つの利点は、HTTP トラフィック用の Web サーバーに存在するネイティブ キャッシュ メカニズムを利用できることです。

REST でのクエリ文字列の弊害を説明しているページへのリンクは次のとおりです

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

于 2008-10-16T05:03:22.783 に答える