REST API可以至少以两种方式拥有参数:

作为url路径的一部分(即/api/resource/parametervalue) 作为查询参数(例如/api/resource?=参数值)

这里的最佳实践是什么?什么时候使用1,什么时候使用2,有什么一般的指导方针吗?

真实世界的例子:Twitter使用查询参数来指定间隔。(http://api.twitter.com/1/statuses/home_timeline.json?since_id=12345&max_id=54321)

把这些参数放在URL路径中会被认为是更好的设计吗?


当前回答

以下是我的观点。

查询参数被用作请求的元数据。它们充当现有资源调用的过滤器或修饰符。

例子:

/ / 2014-08-08 /日历事件

应该给出当天的日历事件。

如果需要特定类别的事件

/日历/ 2014-08-08 /事件吗?类别=约会

或者你需要超过30分钟的比赛

/日历/ 2014-08-08 /事件吗?时间= 30

试金石测试是检查在没有查询参数的情况下是否仍然可以提供请求。

其他回答

这个主题的一个“维度”被忽略了,但它非常重要:有时“最佳实践”必须与我们正在实现或增强REST功能的平台相一致。

实际的例子:

现在许多web应用程序都实现了MVC(模型、视图、控制器)架构。他们假设提供了一个特定的标准路径,当那些web应用程序带有“启用SEO url”选项时更是如此。

这里只提一个相当有名的网络应用程序:OpenCart电子商务商店。 当管理员启用“SEO url”,它期望说url来一个相当标准的MVC格式,如:

http://www.domain.tld/special-offers/list-all?limit=25

在哪里

special-offers是处理URL的MVC控制器(显示special-offers页面) List-all是控制器要调用的动作或函数名。(*) Limit =25是一个选项,表示每页将显示25个项目。

(*) list-all是我使用的一个虚构的函数名。实际上,OpenCart和大多数MVC框架都有一个默认的、隐含的(通常在URL中省略)索引函数,当用户想要执行默认操作时,就会调用该索引函数。真实世界的URL是:

http://www.domain.tld/special-offers?limit=25

现在有了一个类似于上面的相当标准的应用程序或框架结构,你经常会得到一个针对它进行优化的web服务器,为它重写URL(真正的“非SEOed URL”应该是:http://www.domain.tld/index.php?route=special-offers/list-all&limit=25)。

因此,作为开发人员,你要面对的是处理现有的基础设施,并适应你的“最佳实践”,除非你是系统管理员,确切地知道如何调整Apache / NGinx重写配置(后者可能很讨厌!)等等。

因此,你的REST API通常会更好地遵循参考web应用程序的标准,无论是一致性还是易用性/速度(从而节省预算)。

回到上面的实际例子,一个一致的REST API应该是类似这样的url:

http://www.domain.tld/api/special-offers-list?from=15&limit=25

或者(非SEO URLs)

http://www.domain.tld/index.php?route=api/special-offers-list?from=15&limit=25

使用“路径形成”参数和“查询形成”参数的混合。

There are no hard and fast rules, but the rule of thumb from a purely conceptual standpoint that I like to use can briefly be summed up like this: a URI path (by definition) represents a resource and query parameters are essentially modifiers on that resource. So far that likely doesn't help... With a REST API you have the major methods of acting upon a single resource using GET, PUT, and DELETE . Therefore whether something should be represented in the path or as a parameter can be reduced to whether those methods make sense for the representation in question. Would you reasonably PUT something at that path and would it be semantically sound to do so? You could of course PUT something just about anywhere and bend the back-end to handle it, but you should be PUTing what amounts to a representation of the actual resource and not some needlessly contextualized version of it. For collections the same can be done with POST. If you wanted to add to a particular collection what would be a URL that makes sense to POST to.

这仍然留下了一些灰色区域,因为一些路径可以指向多少子代的父资源,这在某种程度上是自由裁量的,取决于他们的使用。这所画出的一条界限是,任何类型的传递表示都应该使用查询参数来完成,因为它不会有底层资源。

为了响应原始问题中给出的真实示例(Twitter的API),参数表示一个可传递查询,它过滤资源的状态(而不是层次结构)。在那个特定的例子中,向由这些约束表示的集合中添加数据是完全不合理的,而且该查询将无法表示为在对象图中有任何意义的路径。

The adoption of this type of resource oriented perspective can easily map directly to the object graph of your domain model and drive the logic of your API to the point where everything works very cleanly and in a fairly self-documenting way once it snaps into clarity. The concept can also be made clearer by stepping away from systems that use traditional URL routing mapped on to a normally ill-fitting data model (i.e. an RDBMS). Apache Sling would certainly be a good place to start. The concept of object traversal dispatch in a system like Zope also provides a clearer analog.

根据REST实现,

1)路径变量用于对资源的直接操作,如联系人或歌曲 前女友. . 获取etc /api/resource/{songid}或 GET etc /api/resource/{contactid}将返回相应的数据。

2)查询perms/参数用于间接资源,如一首歌的元数据 . ., GET / api /资源/ {songid} ?Metadata =genre它将返回特定歌曲的类型数据。

在我看来,参数应该更好地作为查询参数。url用于标识资源,而添加的查询参数用于指定您想要的资源的哪一部分、资源应该具有的任何状态等等。

这是个很有趣的问题。

你可以同时使用它们,关于这个主题没有任何严格的规则,但是使用URI路径变量有一些优点:

缓存: 大多数互联网上的web缓存服务不缓存GET请求时,他们包含查询参数。 他们这样做是因为有很多RPC系统使用GET请求来更改服务器中的数据(失败!!)Get必须是一个安全的方法)

但是如果使用路径变量,所有这些服务都可以缓存GET请求。

层次结构: 路径变量可以表示层次结构: /城市/街道/的地方

它为用户提供了关于数据结构的更多信息。

但如果你的数据没有任何层次关系,你仍然可以使用Path变量,使用逗号或分号:

/城市/经度,纬度

作为规则,当参数的顺序重要时使用逗号,当顺序不重要时使用分号:

/ IconGenerator /红色,蓝色,绿色

除了这些原因之外,在某些情况下,使用查询字符串变量是非常常见的:

当您需要浏览器自动将HTML表单变量放入URI时 当你处理算法的时候。例如谷歌引擎使用查询字符串:

http:// www.google.com/search ? q =休息

总而言之,没有任何强烈的理由使用这种方法,但只要可以,就使用URI变量。