REST风格的URL设计搜索REST风格的URL设计搜索(RESTful URL design fo

2019-05-08 23:10发布

我在寻找代表搜索作为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..20101..103999,不是 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
标签: rest