REST资源URL中的查询字符串

pyt*_*ips 70 rest

我今天与同事讨论过使用REST URL中的查询字符串.拿这两个例子:

1. http://localhost/findbyproductcode/4xxheua
2. http://localhost/findbyproductcode?productcode=4xxheua
Run Code Online (Sandbox Code Playgroud)

我的立场是应该按照示例1设计URL.这更清晰,我认为在REST中是正确的.在我看来,如果产品代码不存在则从示例1返回404错误是完全正确的,而示例2返回404将是错误的,因为页面应该存在.他的立场是,它并不重要,他们都做同样的事情.

由于我们都没有找到具体的证据(诚然,我的搜索并不广泛),我想知道其他人对此的看法.

Dar*_*ler 84

从客户端的角度来看,两个URI之间没有区别.URI对客户端是不透明的.将更干净的地图更清晰地用于服务器端基础架构.

就REST而言,绝对没有区别.我相信为什么这么多人确实认为它只是标识资源的路径组件的原因是因为RFC 2396中的以下行

查询组件是要由资源解释的信息字符串.

此行后来在RFC 3986中更改为:

查询组件包含非分层数据,这些数据与路径组件(第3.3节)中的数据一起用于标识资源

恕我直言,这意味着在识别资源时,查询字符串和路径段在功能上是等效的.


更新以解决史蒂夫的评论.

如果我反对形容词"清洁",请原谅我.这太主观了.你确实有一点,我错过了问题的重要部分.

我认为是否返回404的答案取决于正在检索的资源.它是搜索结果的表示,还是产品的表示?要知道这一点,您真的需要查看导致我们访问URL的链接关系.

如果URL应该返回Product表示,那么如果代码不存在则应返回404.如果URL返回搜索结果,则它不应返回404.

最终结果是URL看起来不是决定因素.话虽如此,通常会使用查询字符串来返回搜索结果,因此当您不想返回404时,使用该样式的URL会更直观.

  • 引用RFC规范很好,但这不是问题的问题.是的,这两个例子在功能上是等价的 - 这没有争议.问题超出了资源的教科书"定义"(他们都适用).对于他的问题,如果查询字符串中的代码不存在,会发生什么?404?那问题的"清洁"方面怎么样?两者都是"有效的",是的,但恕我直言,#1更"清洁",更符合他的要求(与我在下面的StackOverflow的答案相结合). (12认同)
  • 我同意您在更新的答案中给出的比较.查询字符串对于没有404的搜索结果有意义.对于产品代码(根据此问题)404有意义,IMO更常见的是不使用查询字符串.感谢您更新的答案. (5认同)

Ste*_*tti 47

在典型的REST API中,示例#1更正确.资源表示为URI,#1表示更多.在找不到产品代码时返回404绝对是正确的行为.话虽如此,我会略微修改#1,使其更具表现力:

http://localhost/products/code/4xheaua
Run Code Online (Sandbox Code Playgroud)

查看其他精心设计的REST API - 例如,查看StackOverflow.你有:

stackoverflow.com/questions
stackoverflow.com/questions/tagged/rest
stackoverflow.com/questions/3821663
Run Code Online (Sandbox Code Playgroud)

这些都是获得"问题"的不同方式.

  • 我会说:if*code*,`4xheaua`,******产品ID,那么我最好选择`domain/products/4xheaua`.相反,如果*code*只是众多搜索条件中的一个,那么我会选择`domain/products?code = 4xheaua`. (33认同)
  • +1因为findbyproductcode比名词更动词 - 它是一个RPC调用,而不是资源.但是,当您有多个搜索条件而不仅仅是产品代码时,我认为问题会有所改变,答案也会有所改变./ products?size = {size}&color = {color}.我对你的想法很感兴趣. (10认同)

Mic*_*own 9

GET有两个用例

  1. 获取唯一标识的资源
  2. 根据给定标准搜索资源

用例1示例:

/ products/4xxheua
获取唯一标识的产品,如果找不到则返回404.

用例2示例:

/ products?size = large&color = red
搜索产品,返回匹配产品列表(0到多个).

如果我们查看Google Maps API,我们可以看到他们使用查询字符串进行搜索.

例如 http://maps.googleapis.com/maps/api/geocode/json?address=los+angeles,+ca&sensor=false

所以这两种样式都适用于他们自己的用例.