用于搜索的RESTful URL设计

白昼怎懂夜的黑 提交于 2020-02-27 08:13:11

我正在寻找一种合理的方式将搜索表示为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中的汽车联盟怎么样?

什么是代表搜索具有某些属性的汽车的正确方法? 说:给我看看所有带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

到多场案件?


#1楼

对于搜索,请使用查询字符串。 这完全是RESTful:

/cars?color=blue&type=sedan&doors=4

常规查询字符串的一个优点是它们是标准的并且被广泛理解,并且它们可以从form-get生成。


#2楼

这不是REST。 您无法为API中的资源定义URI。 资源导航必须是超文本驱动的。 如果你想要漂亮的URI和大量的耦合,那就好了,但是不要把它称为REST,因为它直接违反了RESTful架构的约束。

请参阅REST的发明者的这篇文章


#3楼

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

搜索

搜索查询是可以的 ,只有你的偏好,应该考虑什么。 加入搜索时会出现有趣的部分(见下文)。

/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)

加入搜索
搜索红色蓝色黑色汽车行驶3门在车库编号1..20101..103999,不是 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 ,dates /articles/{year}/{month}/{day} ..当你省略任何最后一段时,你会立即知道你得到了什么。

所以..,所有这些字符都是允许未编码的

  • 未保留: a-zA-Z0-9_.-~
  • reserved ;/?:@=&$-_.+!*'(),
  • 不安全*: <>"#%{}|\\^~[]`

*为什么不安全以及为什么要编码: RFC 1738见2.2

RFC 3986见2.2
尽管我之前曾说过,但这里有一个共同的区分,这意味着一些更重要。

  • 通用分隔符:: :/?#[]@
  • sub-delimeters: !$&'()*+,;=

更多阅读:
层次结构: 见2.3见1.2.3
url路径参数语法
CSS3属性匹配
IBM:RESTful Web服务 - 基础知识
注意:RFC 1738由RFC 3986更新


#4楼

我的建议是这样的:

/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而不是查询字符串的另一个优点是,您可以利用Web服务器上存在的HTTP流量的本机缓存机制。

这是一个描述REST中查询字符串邪恶的页面的链接: http ://web.archive.org/web/20070815111413/http://rest.blueoxen.net/cgi-bin/wiki.pl? QueryStringsConsideredHarmful

我使用了Google的缓存,因为普通页面对我来说不起作用,这里也是这个链接: http//rest.blueoxen.net/cgi-bin/wiki.pl?QueryStringsConsideredHarmful


#5楼

Justin的答案可能是要走的路,尽管在某些应用程序中将特定搜索本身视为资源可能是有意义的,例如,如果您想支持已命名的已保存搜索:

/search/{searchQuery}

要么

/search/{savedSearchName}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!