我在寻找代表搜索作为RESTful URL的合理途径。
设置:我有两个型号,轿车和车库,其中汽车可以在车库。 所以,我的网址如下所示:
/car/xxxx
xxx == car id
returns car with given id
/garage/yyy
yyy = garage id
returns garage with given id
一辆汽车可以在自己的(因而/车)的存在,或者它可以在一个车库存在。 什么是代表,也就是说,在一个给定的车库的所有汽车的正确方法? 就像是:
/garage/yyy/cars ?
如何在车库YYY ZZZ和汽车的结合?
什么是代表具有某种属性的汽车搜索的正确方法? 你说:我展示四门全蓝轿车:
/car/search?color=blue&type=sedan&doors=4
还是应/汽车呢?
使用“搜索”似乎不妥那里 - 有什么更好的办法/学期? 如果它仅仅是:
/cars/?color=blue&type=sedan&doors=4
如果搜索参数是PATHINFO或QUERYSTRING的一部分吗?
总之,我正在寻找一个跨模型REST URL设计指导,并为搜索。
[更新]我喜欢Justin的答案,但他并不涵盖多领域的搜索情况:
/cars/color:blue/type:sedan/doors:4
或类似的东西。 我们如何从去
/cars/color/blue
在多场的情况下?
Answer 1:
对于搜索,使用的查询字符串。 这是完全基于REST:
/cars?color=blue&type=sedan&doors=4
定期查询字符串的一个优点是,他们是标准的广泛理解,他们可以从生成表单搞定。
Answer 2:
REST风格的漂亮的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
。
搜索
该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对象是REST风格的? **
选项列表
/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)
加入搜索
搜索红色或蓝色或黑色汽车行驶3门在车库编号1..20或101..103或999,但不是 5 /garage[id=1-20,101-103,999,!5]/cars[color=red,blue,black;doors=3]
然后,您可以构建更复杂的搜索查询。 (请看CSS3属性匹配用于匹配的子串的概念。例如搜索包含“bar”的用户user*=bar
)。
结论
无论如何,这可能是你最重要的部分,因为你可以做不过它,你就像毕竟只是记住,REST风格的 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服务-基础知识
注:RFC 1738是由RFC 3986更新
Answer 3:
尽管具有在路径中的参数具有一定的优势,还有,IMO,一些因素outweighing。
不需要搜索查询所有字符都允许在URL中。 大多数标点符号和Unicode字符将需要URL编码的查询字符串参数。 我同样的问题摔跤。 我想在URL中使用XPath,但不是所有的XPath语法是一个URI路径兼容。 因此,对于简单路径, /cars/doors/driver/lock/combination
将是适当的定位“ combination
驾驶员侧车门XML文档中的”元素。 但是/car/doors[id='driver' and lock/combination='1234']
是不那么友好。
有过滤是根据它的属性中的一个的资源和指定资源之间的差。
例如,由于
/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
似乎累赘。
Answer 4:
为了扩大对彼得的答案 - 你可以做搜索一流的资源:
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)
搜索资源将有字段的颜色,使模型,garaged状态等,并可以在XML,JSON,或任何其他形式来指定。 像汽车和车库的资源,你可以限制访问基于认证搜索。 谁经常运行同一个搜索可以将它们存储在自己的配置文件的用户,使他们无需重新创建。 URL是足够短,在许多情况下,他们可以很容易地通过电子邮件进行交易。 这些存储的搜索可以自定义RSS Feed的基础上,依此类推。
有使用搜索时,你认为他们是资源的多种可能性。
这个想法是更详细地解释这个Railscast 。
Answer 5:
Justin的答案很可能是要走的路,尽管在某些应用中,可能是有意义的考虑特定的搜索,但其本身的资源,例如,如果你想支持命名保存的搜索为:
/search/{searchQuery}
要么
/search/{savedSearchName}
Answer 6:
这不是休息。 你不能为你的API内部资源定义的URI。 资源导航必须是超文本驱动。 没关系,如果你想漂亮的URI和重耦合量,但就是不把它休息,因为它直接违反了RESTful架构的限制。
看到这个文章通过REST的发明者。
Answer 7:
我用两种方法来实现搜索。
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
Answer 8:
虽然我喜欢Justin的反应,我觉得它更准确地代表了一个过滤器,而不是搜索。 如果我想了解名称以凸轮启动汽车?
我看到它,你可以建立它变成你处理特定资源的方式的方式:
/汽车/ CAM *
或者,你可以简单地把它添加到过滤器:
/汽车/门/ 4 /名/ CAM * /颜色/红,蓝,绿
就个人而言,我更喜欢后者,但我绝不是在REST的专家(最早听说过它只有2个左右星期前...)
Answer 9:
REST风格不建议在网址/汽车/搜索使用的动词是不宁静。 过滤/搜索/分页您的API的正确的方法是通过查询参数。 但是可能有情况下,当你必须打破常态。 例如,如果要跨多个资源搜索,那么你必须使用像/搜索?Q =查询
你可以通过http://saipraveenblog.wordpress.com/2014/09/29/rest-api-best-practices/了解设计的RESTful API的最佳实践
Answer 10:
另外我还建议:
/cars/search/all{?color,model,year}
/cars/search/by-parameters{?color,model,year}
/cars/search/by-vendor{?vendor}
在这里, Search
被视为一个子资源Cars
资源。
Answer 11:
有你的情况下,这里有很多不错的选择。 不过,你应该考虑使用POST体。
查询字符串是非常适合你的榜样,但如果你有更复杂的东西,如项目或布尔条件语句的任意长的列表,你可能希望定义后的文件,客户端发送了POST。
这使得搜索更加灵活的描述,以及避免了服务器URL长度的限制。
Answer 12:
我的建议是这样的:
/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,而不是查询字符串的另一个好处是,你可以采取HTTP流量的Web服务器上存在的本地缓存机制的优势。
下面就来描述REST查询字符串的罪恶一个页面的链接: http://web.archive.org/web/20070815111413/http://rest.blueoxen.net/cgi-bin/wiki.pl?QueryStringsConsideredHarmful
我用谷歌的缓存,因为正常的页面没有工作对我来说这里是一个链接,以及: http://rest.blueoxen.net/cgi-bin/wiki.pl?QueryStringsConsideredHarmful
文章来源: RESTful URL design for search