用于搜索的RESTful URL设计
我正在寻找一种合理的方法,将搜索表示为RESTful URL 设置:我有两个模型,汽车和车库,汽车可以在车库里。所以我的URL看起来像:用于搜索的RESTful URL设计,rest,Rest,我正在寻找一种合理的方法,将搜索表示为RESTful URL 设置:我有两个模型,汽车和车库,汽车可以在车库里。所以我的URL看起来像: /car/xxxx xxx == car id returns car with given id /garage/yyy yyy = garage id returns garage with given id 汽车可以独立存在(因此为/Car),也可以存在于车库中。比如说,代表某个车库中所有汽车的正确方式是什么?比如: /garage/
/car/xxxx
xxx == car id
returns car with given id
/garage/yyy
yyy = garage id
returns garage with given id
汽车可以独立存在(因此为/Car),也可以存在于车库中。比如说,代表某个车库中所有汽车的正确方式是什么?比如:
/garage/yyy/cars ?
车库里的汽车联盟yyy和zzz怎么样
搜索具有特定属性的汽车的正确方式是什么?说:让我看看所有四门蓝色轿车:
/car/search?color=blue&type=sedan&doors=4
还是应该换成汽车
使用“搜索”似乎不合适——有什么更好的方法/术语?应该是:
/cars/?color=blue&type=sedan&doors=4
搜索参数应该是PATHINFO或QUERYSTRING的一部分吗
简而言之,我正在寻找关于跨模型RESTURL设计和搜索的指导
[更新]我喜欢Justin的回答,但他没有涵盖多字段搜索案例:
/cars/color:blue/type:sedan/doors:4
或者类似的。我们从何而来
/cars/color/blue
对于多字段情况?我的建议是:
/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 :) )
编辑:
希望这能给你一个想法。本质上,您的RESTAPI应该易于发现,并使您能够浏览数据。使用URL而不是查询字符串的另一个优点是,您可以利用web服务器上存在的用于HTTP流量的本机缓存机制
下面是一个页面链接,该页面描述了REST中查询字符串的弊端:
我使用谷歌的缓存是因为普通页面对我不起作用,这里还有一个链接:
贾斯廷的答案可能是走的路,尽管在一些应用程序中,将特定搜索视为自己的资源是有意义的,例如,如果您想支持命名的保存搜索:
/search/{searchQuery}
/cars?q.garage.street.eq=FirstStreet&q.color.ne=red&offset=300&max=100
或
虽然我喜欢贾斯汀的回答,但我觉得它更准确地代表了一个过滤器而不是一个搜索。如果我想知道名字以cam开头的汽车怎么办?
在我看来,您可以将其构建为处理特定资源的方式:
/汽车/凸轮*
或者,您可以简单地将其添加到过滤器中:
/汽车/门/4/名称/凸轮*/颜色/红、蓝、绿
就个人而言,我更喜欢后者,但我绝对不是REST方面的专家(在大约两周前才第一次听说过它…虽然在路径中使用参数有一些优势,但在我看来,有一些重要因素
- URL中不允许搜索查询所需的所有字符。大多数标点符号和Unicode字符都需要URL编码为查询字符串参数。我正在努力解决同样的问题。我希望在URL中使用XPath,但并非所有XPath语法都与URI路径兼容。因此,对于简单路径,
适合在驾驶员车门XML文档中定位“/cars/doors/driver/lock/composition
”元素。但是composition
并不友好/car/doors[id='driver'和lock/composition='1234']
- 根据资源的一个属性筛选资源与指定资源之间存在差异
比如说,
返回所有汽车的所有颜色列表(返回的资源是颜色对象的集合)/cars/colors
将返回红色、蓝色或绿色的颜色对象列表,而不是汽车集合 要归还汽车,路径将是/cars/colors/red、blue、green
或/cars?color=红、蓝、绿
/cars/search?color=红、蓝、绿
- 路径中的参数更难读取,因为名称/值对与路径的其余部分(不是名称/值对)没有隔离
最后一点意见。我更喜欢
/garages/yyy/cars
(总是复数)而不是/garage/yyy/cars
(可能是原始答案中的一个输入错误),因为它避免了在单数和复数之间改变路径。对于添加了“s”的单词,更改并不糟糕,但是将/person/yyy/friends
更改为/people/yyy
似乎很麻烦。要扩展Peter的答案,您可以将搜索设为一流资源:
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或任何其他格式指定。与汽车和车库资源一样,您可以基于身份验证限制对搜索的访问。经常运行相同搜索的用户可以将它们存储在他们的配置文件中,这样就不需要重新创建它们。URL将足够短,在许多情况下,它们可以通过电子邮件轻松交易。这些存储的搜索可以作为定制RSS提要的基础,等等
当您将搜索视为资源时,使用搜索有许多可能性
这篇文章更详细地解释了这个想法。对于搜索,请使用querystring。这是非常安静的:
/cars?color=blue&type=sedan&doors=4
常规查询字符串的一个优点是,它们是标准的且被广泛理解,并且可以从表单get生成。这不是REST。不能为API内的资源定义URI。资源导航必须是超文本驱动的。如果您想要漂亮的uri和大量的耦合,这很好,但不要称之为REST,因为它直接违反了RESTful体系结构的约束
REST的发明者看到了这一点。RESTful漂亮的URL设计是关于基于结构(类似目录的结构,日期:articles/2005/5/13,object及其属性,…)显示资源,斜杠
/
表示层次结构,请改用-id
层次结构
我个人更喜欢:
/garage id/cars/car id
/汽车/汽车id#适用于不在车库内的汽车
如果用户删除了/car id
部分,则会带来车辆
预览-直观。用户确切知道
/cars?color=blue&type=sedan&doors=4
/cars?q.garage.id.eq=1
/cars?q.garage.street.eq=FirstStreet&q.color.ne=red&offset=300&max=100
POST /searches => Create
GET /searches/1 => Recover search
GET /searches/1?offset=300&max=100 => pagination in search
{
"$class":"test.Car",
"$q":{
"$eq" : { "color" : "red" },
"garage" : {
"$ne" : { "street" : "FirstStreet" }
}
}
}
/cars/search/all{?color,model,year}
/cars/search/by-parameters{?color,model,year}
/cars/search/by-vendor{?vendor}