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

Oli*_*ohm 18 rest http optimistic-locking web

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

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

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

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

Wil*_*ler 25

从您的链接到规范:

如果没有实体标签匹配,或者如果给出"*"并且不存在当前实体,则服务器必须不执行所请求的方法,并且必须返回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将在版本冲突发生的地方使用,作为无条件请求的一部分.