用于搜索的RESTful URL设计
我正在寻找一种合理的方式将搜索表示为RESTful网址。
设置:我有两个模型,汽车和车库,汽车可以在车库。 所以我的网址看起来像:
/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的汽车联盟?
代表具有特定属性的汽车搜索的正确方法是什么? 说:给我看看所有4门轿车的蓝色轿车:
/car/search?color=blue&type=sedan&doors=4
或者它应该是/汽车呢?
“搜索”的使用在那里似乎不合适 - 什么是更好的方式/术语? 它应该是:
/cars/?color=blue&type=sedan&doors=4
搜索参数应该是PATHINFO还是QUERYSTRING的一部分?
总之,我正在寻找一个很好的指导/教程交叉模型REST的网址设计,并进行搜索。
[更新]我喜欢贾斯汀的回答,但他没有涉及多领域搜索案例:
/cars/color:blue/type:sedan/doors:4
或类似的东西。 我们如何去
/cars/color/blue
到多场的情况下?
为了搜索,请使用querystrings。 这是完美的RESTful:
/cars?color=blue&type=sedan&doors=4
常规querystrings的一个好处是它们是标准的并且被广泛理解,并且它们可以从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
。
搜索
searchquery可以,因为它只是你的偏好,应该考虑的是什么。 有趣的部分来自加入搜索时(见下文)。
/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或999但不是 5 /garage[id=1-20,101-103,999,!5]/cars[color=red,blue,black;doors=3]
然后,您可以构建更复杂的搜索查询。 (查看匹配子串的想法的CSS3属性匹配,例如搜索包含“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服务 - 基础知识
注意:RFC 1738由RFC 3986更新
虽然路径中的参数具有一些优势,但IMO有一些超标因素。
并非所有搜索查询所需的字符都可以在网址中使用。 大多数标点符号和Unicode字符需要被URL编码为查询字符串参数。 我正在与同样的问题搏斗。 我想在URL中使用XPath,但并非所有XPath语法都与URI路径兼容。 因此,对于简单的路径, /cars/doors/driver/lock/combination
将适合于在驱动程序的门XML文档中找到“ combination
”元素。 但是/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'的单词,变化并不那么糟糕,但将/people/yyy
/person/yyy/friends
更改为/people/yyy
似乎很麻烦。
上一篇: RESTful URL design for search
下一篇: Why does `type(myField)` return `<type 'instance'>` and not `<type 'Field'>`?