如何以幂等方式重命名资源?

时间:2013-10-15 17:50:56

标签: rest http-put idempotent

我实施了一个重命名公司的API,如下所示:

PUT /companies/A
{
  "name": "B"
}

将返回HTTP 301Location标题指向公司的新URI:/companies/B

如果有If-Match标题,我怎样才能使此操作具有幂等性?

  1. 没有If-Match标题:如果用户尝试重命名不存在的公司,我希望服务器返回HTTP 404,但我不能这样做,因为那时合法重命名操作不是幂等的(它们第一次返回301,后续调用时返回404。这是有问题的,因为我希望客户能够区分失败的重命名(公司不存在)与已经发生的重命名。

  2. 使用If-Match标头:如果公司的ETag取决于公司名称,则后续重命名操作将失败,因为前提条件不再成立。同样,这使得操作似乎失败了,实际上它已经发生了。

3 个答案:

答案 0 :(得分:6)

好的,这已经两年了,但是我会回答它,以防其他人像我一样偶然发现它。

简短的回答是,从HTTP的角度来看,重命名(移动)资源幂等,您应该使用POST代替PUT。< / p>

答案很长:PUT是一个“创建或替换”操作,由RFC 2616定义如下(强调我的):

  

PUT方法请求在提供的Request-URI 下存储所包含的实体。

RFC 7231(此时此问题仅作为草案存在),更明确地说明了这一点:

  

PUT方法请求目标资源的状态     用表示定义的状态创建或替换     包含在请求消息有效负载中。成功的PUT     表示会建议后续的GET     目标资源将导致等效表示     已通过200OK)回复发送。

由于成功重命名会导致资源在不同的位置可用,因此PUT不适用。

PS。您可以通过在请求正文中包含公司的某种唯一标识符(无论其名称或其他属性)来使用PUT,这样您就可以检测以前的重命名并发出适当的重定向。然而,我认为这违反了协议,POST会更合适。

答案 1 :(得分:2)

PUT操作成功,应该返回200或201.对同一资源的后续请求应返回301,其中相应的响应主体指示新资源的URI。

404应仅适用于真正无法找到的资源,即那些不存在且从未拥有的资源。

protocol中所述,幂等并不意味着该调用始终返回相同的内容。这意味着没有副作用。此外,幂等在错误条件下不适用,除了2xx之外的任何东西(如301)都是。

我真的很佩服通过规范来做到正确的承诺,但就像所有事情一样,它需要解释。

答案 2 :(得分:0)

我不认为3xx在这里有意义。 PUT操作成功,因此应返回2xx。 301意味着资源不是请求者认为的资源。

一般来说,当他们真正想要MOVE时,我一直对不使用MOVE的人感到好笑: - )