3
4

3 回答 3

2

让我们从 REST 不是像 SOAP 那样的固定协议开始,它只是一种构建服务的方法,类似于将语言描述为面向对象的方式。

综上所述,我建议如下处理。


将 RESTful 调用视为函数声明。

GET /foo
foo()

有些函数需要参数。

GET /foo?start=??&count=??
foo(start, count)

有些语言支持默认参数,有些则不支持;您可以自己决定如何处理参数。

使用默认参数,您可以假设该函数被定义为

foo(start = 0, count = 10)

所以调用GET /foo实际上等同于GET /foo?start=0&count=10,而调用 toGET /foo?start=100将等同于GET /foo?start=100&count=10.

如果您想要默认参数,您可以强制 API 的用户显式设置startand count

foo(start, count)

这样调用GET /foo将返回400 Bad Request状态代码,但调用GET /foo?start=0&count=10将返回200 OK状态代码以及指定范围包含的内容。

无论哪种情况,您都必须决定如何处理错误,例如

GET /foo?start=-10&count=99999999

如果参数有最大值和最小值,您需要决定是标准化参数还是简单地返回错误。前面的示例可能会返回一个400 Bad Request状态码,但它也可能被限制为:

GET /foo?start=0&count=1000

最后,由您来决定在您的应用程序的上下文中什么是最有意义的。

于 2012-02-09T15:08:45.890 回答
2

从 RESTful 的角度来看,我认为同样处理两种表示是完全可以的。考虑一个您要下载的具有多个版本的软件,最新的版本是 3.8。因此,如果您想获得最新版本,您可以同时解决它,GET /software/version/latest.zip直到GET /software/version/3.8.zip出现更新版本。所以两个不同的链接指向同一个资源。

我喜欢想象分页几乎相同。在第一页上总是有最新的文章。所以如果没有page提供 -parameter,你可以简单地暗示它是 1。

使用rel属性的方法朝着稍微不同的方向发展。它是 Google 创建的,旨在更好地处理重复内容的问题,主要用于区分“主”页面和分页页面。以下是如何使用它:

//first page:
<link rel="next" href="http://www.foo.com/foo?page=2" />

//second page:
<link rel="prev" href="http://www.foo.com/foo?page=1" />
<link rel="next" href="http://www.foo.com/foo?page=3" />

//third and last page:
<link rel="prev" href="http://www.foo.com/foo?page=2" />

因此,从 SEO 的角度来看,使用这些元素是一个好主意(并由 Google 推荐)。它们还与 REST 的面向资源的思想和资源的超媒体表示完美契合。

选择您的建议之一,我认为这303 See Other是正确的方法。它旨在用于此类目的,是规范化资源的好方法。您可以通过许多 URI 使它们可用,但有一个“真实” URI 用于表示(例如具有不同版本的软件)。

根据规范,响应应如下所示:

303 See Other
Location: http:www.foo.com/foo?page=1

<a href="http:www.foo.com/foo?page=1">http:www.foo.com/foo?page=1</a>

因此,您提供具有“真实”表示的 Location-header,并且正文应包含链接到新 URI 的超文本文档。请注意,根据规范,客户端应该向 Location 的值发送 GET 请求,但并非必须如此。


//编辑作为对您评论的回答(是的,在没有证明的情况下声称某些东西真的很糟糕:-) - 我的错!):

Google于 2011 年 9 月在官方网站管理员中心博客rel="next"上展示了和属性。它们可以附加到(或在某些情况下代替)标签使用。rel="prev"rel="canonical"

在这些链接下,您可以找到它们之间的差异解释:

  • rel="next"rel="prev" 链接元素是“指示分页系列中组件 URL 之间的关系”
  • rel="canonical"允许您公开指定您的首选 URL 版本”

因此,它们之间存在细微差别。因此,您可以将问题分解为规范问题:有多个 URL 指向同一资源(/foofoo?page=1您有 URL 的首选版本 ( foo?page=1)。所以现在有一些 RESTful 方法的选项:

  • 如果查询中没有page给出 -parameter,则在处理时使用默认值(例如 1)。我认为在这种特定情况下,即使您指出它是不好的做法,也可以使用默认值。
  • 响应303 See Other在Location -header中提供首选 URL (如上所述)。我认为3xx -response 是处理重复/规范内容的最佳(并且很可能是 RESTfully 预期的)方式。
  • 如果您想强制客户端提供-parameter(如 zzzzBov 在他的回答中解释的那样),请以400 Bad Request响应。page请注意,此响应没有诸如Location标头之类的内容(如您的问题中所假设的那样),因此请求失败和/或正确 URL(如果给出)的解释必须转到响应的实体主体。另外,请注意,根据规范,当客户端提交错误/格式错误的表示(!不是 URL!)以及PUTorPOST请求时,通常使用此响应。所以请记住,这对客户来说也可能有点模棱两可。

就个人而言,我不认为您建议使用405 Method Not Allowed进行响应是一个好主意。根据规范,您必须提供一个Allow -header 列出允许的方法。但是在这个资源上可以允许哪些方法呢?我只能想到POST。但是,如果您也不想让客户接受POST它,您也可以用403 Forbidden来解释为什么它被禁止,或者如果您不想告诉它为什么被禁止,则用404 Not Found来回应。所以它也可能有点模棱两可(在我看来)。

正如您在问题中提出的那样,将link-elements 与提到的-attributes 一起使用本质上不是“RESTful”,因为它只是在资源表示中解决的超媒体。rel但是您的问题(据我所知)是您想决定如何响应特定请求以及要服务的表示。但这仍然不是绝对没有意义的:

您可以将整个 SEO 问题视为 using 的副作用rel="next/prev/canonical",但请记住,它们还会创建连接性(作为具有链接的质量),这是 REST 的特征之一(请参阅Roy Fielding 的论文)。

如果您想深入了解 RESTful Web 服务(这完全值得),我建议您阅读Leonard Richardson 和 Sam Ruby所著的RESTful Web Services一书。

于 2012-02-09T15:18:46.017 回答
0

在某些情况下,不为客户端隐式管理任何内容可能会导致覆盖复杂的界面,例如消费者不是技术人员或不打算在界面之上构建的示例,例如在网页中。在这种情况下,甚至 200 也可能是合适的。

在其他情况下,我同意隐式管理将是一个坏主意,因为消费者希望能够正确预测响应以及可能需要简单规范的地方。在这种情况下,405、400 和 303。

这是一个上下文问题。

于 2012-02-10T14:29:41.947 回答