由于乐观锁定失败,用于拒绝PUT的HTTP状态代码

时间:2013-10-01 17:11:13

标签: http rest web optimistic-locking

假设我想实现某种乐观锁定并使用ETag来指示最新的资源状态。这意味着,客户将在If-Match进行更新时使用PUT标头。

根据HTTP spec,如果为412 Precondition failed标头提供的ETag与资源的当前状态不匹配,则服务器必须返回If-Match

然而,409 Conflict似乎更接近我想要在语义上表达的内容,特别是因为它给出了在响应中包含的指南。

如果未能匹配409标题中提供的ETag,则返回If-Match是否非常错误?

1 个答案:

答案 0 :(得分:22)

从您的指向链接:

  

如果没有实体标签匹配,或者如果给出“*”并且不存在当前实体,则服务器必须不执行所请求的方法,并且必须返回412(Precondition Failed)响应。当客户端想要阻止更新方法(如PUT)修改自客户端上次检索它以来已更改的资源时,此行为最有用。

因为规范需要HTTP 412(实际上它使用“必须”),并且因为很明显它们恰好考虑了正在讨论的用例,所以HTTP 412似乎是正确的响应代码。

无论如何,412是非常合理的。请求说有条件地进行更新。 412说条件失败,所以服务不会这样做。特别是因为412是条件请求概念的良好匹配; 409似乎附加于某种特定的拒绝,这可能是也可能不是有条件的。例如,我可以看到一个服务返回409以响应无条件请求发送内部冲突的内容。

但请参阅以下内容,同样来自规范:

  

10.4.10 409冲突

     

由于与资源的当前状态发生冲突,无法完成请求。此代码仅在预期用户可能能够解决冲突并重新提交请求的情况下才允许。响应主体应该包含足够的信息供用户识别冲突的来源。理想情况下,响应实体将包含足够的信息供用户或用户代理解决问题;但是,这可能是不可能的,也不是必需的。

     

最有可能发生冲突以响应PUT请求。例如,如果正在使用版本控制并且包含PUT的实体更改为与早期(第三方)请求所产生的资源冲突的资源,则服务器可能会使用409响应来指示它无法完成请求。在这种情况下,响应实体可能包含由响应Content-Type定义的格式的两个版本之间的差异列表。

无论如何,规范似乎在条件请求上下文中需要412,同时暗示版本冲突是409s的关键驱动因素。可能是409将在版本冲突发生的地方使用,作为无条件请求的一部分。