RESTful设计:应该重命名资源永久阻止旧URI吗?

时间:2012-11-26 03:10:22

标签: rest api-design

我正在尝试理解RESTful Web Services第274页HTTP PUT部分。针对不存在的资源发出PUT会创建资源。如果PUT导致现有资源移动,则会返回新位置HTTP 301 (Moved Permanently)。对旧URI的请求返回HTTP 301,404或410。

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

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

我看到使用HTTP 301的以下好处:

  • 并发:如果一个用户重命名公司而另一个用户正在导航到某个部门,那么后者将获得HTTP 404,尽管他们没有做错任何事。 HTTP 301允许我们将第二个用户无缝重定向到新URI。
  • 书签:人和计算机都需要将URI标记为长期存储。人类在论坛中发布链接。计算机使用URI进行缓存和用户首选项。

我发现HTTP 301存在以下问题:

  • 阻止长期资源演变:部门A在其生命周期内重命名为BCD。几年后,有人想创建部门A,而D则无法这样做。公平地说,我想不出任何可能发生这种情况的实际例子,所以也许这不是问题。
  • API版本限制其使用:随着新API版本的发布和旧版本的删除,即使root资源也会随着时间而变化。如果客户端无法以旧方式访问新资源,那么返回HTTP 301的重点是什么?

适当的行动方案是什么?是否应对网址层次结构进行不同的建模?行为/反应应该不同吗?

3 个答案:

答案 0 :(得分:1)

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

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

GET /oldurl
PUT /newurl
DELETE /oldurl

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

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

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

e.g。 HTML网站是REST实现的标准示例

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

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

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

服务入口点= /
/链接到/ http:// http:// myservice / rels / companies“的公司 / company链接到/ companies / new-company-name,其中包含rel“item”

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

答案 1 :(得分:0)

我会返回一个简单的404。这表示没有任何内容与请求的uri匹配,并且documentation指定:

  

没有说明该病症是暂时的还是永久性的。

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

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

  

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

答案 2 :(得分:0)

回答我自己的问题:

  1. 我想不出任何保持HTTP 301永远会导致问题的实际例子。
  2. 链接并不意味着能够在API版本中生存。一个版本的资源不应引用其他版本的资源(即使使用HTTP 301)。如果资源的URI因API更改而发生更改,则旧API应继续使用旧URI。
  3. 更新:根据Willy Tarreau幂等性,只需要应用程序重定向一小段时间。一旦客户端完成重试请求,就不再需要重定向(至少不需要重新定向)。您可能希望将重定向保留更长时间,以支持固定链接等功能,但规范中的任何内容都不会强制您使用。