6

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

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

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

我怎样才能使这个操作在有和没有If-Match标题的情况下是幂等的?

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

  2. 带头If-Match:如果公司的ETag依赖于公司名称,那么后续的重命名操作将失败,因为前提条件不再成立。同样,这使得操作看起来失败,而实际上它已经发生了。

4

3 回答 3

7

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

简短的回答是,从 HTTP 的角度来看,重命名(移动)资源不是幂等的,您应该POST使用PUT.

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

PUT方法请求将封闭的实体存储在提供的 Request-URI 下

RFC 7231(当时提出这个问题仅作为草稿存在),更清楚地说明了这一点:

PUT方法请求目标资源的状态被创建或替换为请求消息有效负载中包含的表示定义的状态。给定表示的成功PUT将表明同一目标资源上的后续将导致在( ) 响应GET中发送等效表示。200OK

因为成功的重命名将导致资源在不同的位置可用,PUT所以不适用。

PS。也许您可以PUT通过在请求正文中包含公司的某种唯一标识符(无论其名称或其他属性如何)来完成这项工作,这将允许您检测以前的重命名并发出适当的重定向。尽管如此,我认为它违反了协议,并且POST会更合适。

于 2015-10-19T09:00:05.607 回答
2

PUT 操作成功并应返回 200 或 201。对同一资源的后续请求应返回 301,并带有指示新资源 URI 的相应响应正文。

404 应该只用于真正找不到的资源,即不存在且从未有过的公司。

协议中所述,幂等并不意味着调用总是返回相同的东西。这意味着没有副作用。此外,幂等性不适用于错误条件,除了 2xx(如 301)以外的任何错误条件。

我真的很钦佩按照规范正确处理它的承诺,但与所有事情一样,它需要解释。

于 2013-10-15T18:15:04.780 回答
0

我认为 3xx 在这里没有意义。PUT 操作成功,所以它应该返回一个 2xx。301 表示资源不在请求者认为的位置。

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

于 2013-10-15T18:00:27.793 回答