3

我正在尝试了解RESTful Web 服务页面 274 部分HTTP PUT。对PUT不存在的资源进行发布会创建资源。如果PUT导致现有资源移动,则返回HTTP 301(永久移动)和新位置。对旧 URI 的请求返回 HTTP 301、404 或 410。

我的问题是关于返回HTTP 301。这似乎意味着资源永远保留旧 URI 的所有权。

考虑:/companies/{companyName}/departments/{departmentName}

我看到使用以下好处HTTP 301

  • 并发:如果一个用户重命名一家公司,而另一个用户正在导航到一个部门,尽管他们没有做错任何事情,但后者将获得 HTTP 404。HTTP 301允许我们无缝地将第二个用户重定向到新的 URI。
  • 书签:人类和计算机都需要为 URI 添加书签以进行长期存储。人类在讨论论坛中发布链接。计算机将 URI 用于缓存目的和用户偏好。

我看到以下问题HTTP 301

  • 阻止长期资源演变:在其生命周期内,部门A被重命名为B和。几年后,有人想创建部门,但被. 公平地说,我想不出任何会发生这种情况的实际例子,所以也许这不是问题。CDAD
  • API 版本限制了它的使用:随着新 API 版本的发布和旧版本的删除,甚至根资源也会随着时间而变化。HTTP 301如果客户端不能以与旧资源相同的方式访问新资源,那么返回有什么意义?

什么是适当的行动方案?URL 层次结构是否应该以不同的方式建模?行为/反应应该不同吗?

4

3 回答 3

1
如果 PUT 导致现有资源移动,则返回 HTTP 301 和新位置。

从技术上讲,您不能在 HTTP 中移动资源。如果您作为客户端操作资源,您正在做的是:

GET /oldurl
PUT /newurl
DELETE /oldurl

服务器不会知道新 URL 是资源在旧 URL 处的新位置,也没有客户端可以使用通用 HTTP 方法建立的重定向 URL 持久性的概念。如果服务提供允许您移动项目的 API,例如通过传递某些参数,并且基本上在幕后执行上述操作,但也在此过程中创建重定向,那么该重定向是否是由服务决定的是否可以用新操作覆盖PUT,以及要使用哪种重定向。

我的理解是,当帖子标题被重命名时,我们应该跟踪旧名称并在客户端引用旧地址时返回 HTTP 301。

这与 REST 无关,是Cool URIs don't change的一种表现。在 RESTful 服务中,通过可从服务入口点访问的资源或资源序列链接到新 URL 就足够了。

例如,HTML 网站是 REST 实现的规范示例

服务入口点 = /blog
/blog 链接到 /blog/archive
/blog/archive 链接到 /blog/new-post-title

由于博客服务旨在供人们使用 Web 浏览器使用,因此预计他们可能希望将 URL 加入书签以便以后重新访问。这就是重定向的用途。

机器对机器的 API 必须做类似的事情:

服务入口点 = //
链接到 /companies,rel 为“http://myservice/rels/companies”
/companies 链接到 /companies/new-company-name,rel 为“item”

无需提及旧的公司名称,因为机器不会为某个位置添加书签,而是每次都从入口点开始导航。

于 2012-11-26T12:03:05.450 回答
0

我会返回一个简单的404. 这表示没有与请求的 uri 匹配的内容,并且从文档中指定:

没有说明这种情况是暂时的还是永久性的。

这样,创建新资源来替换过去某个时候存在的资源是完全有效的。

否则,如果您要通过重命名来移动资源,则始终可以返回 a 302,指定资源位于不同的位置。您可以返回此状态,直到生成替换为止。用户必须继续使用这些标头以确保资源仍然被重新定位:

由于重定向有时可能会改变,客户端应该继续使用 Request-URI 来处理未来的请求。

于 2012-11-26T04:47:34.887 回答
0

Answering my own question:

  1. I can't think of any practical example where keeping HTTP 301 forever would cause problems.
  2. Links are not meant to survive across API versions. Resources from one version should not reference resources from another version (even using HTTP 301). If a resource's URI changes as the result of an API change, the old API should keep on using the old URI forever.

UPDATE: According to Willy Tarreau idempotency only requires the application to redirect for a short period of time. Once the client has finished retrying a request, the redirect is no longer needed (at least not for idempotency). You might want to keep redirects around for a longer period of time, to support features such as permalinks, but nothing in the specification forces you to.

于 2012-12-06T21:46:57.993 回答