用于搜索的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
    尽管我之前说过,但这里有一个常见的区别,即有些“比”更重要。

  • 通用的delimeters:: :/?#[]@
  • 子分隔符: !$&'()*+,;= ,; !$&'()*+,;=
  • 更多阅读:
    层次结构:见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似乎很麻烦。

    链接地址: http://www.djcxy.com/p/6997.html

    上一篇: RESTful URL design for search

    下一篇: Why does `type(myField)` return `<type 'instance'>` and not `<type 'Field'>`?