编辑冲突和409与412响应

时间:2013-06-12 22:18:06

标签: api http rest

我们有一个REST API,用于处理应用程序后端。我们需要实现一个冲突预防功能,编辑请求(POST / PUT)将检查记录是否在客户端上次读取和现在之间未被修改,如果是,则会告诉客户端存在冲突。

问题是如何发送冲突检查标记(最有可能是时间戳,但我们不想强制要求)以及如何返回错误。

我们希望尽可能使用标准的REST模式,所以我们在这里考虑的解决方案:

  • 使用 If-Modified-Since 。这里的问题是它要求使用时间戳,并且规范说你必须返回412.我们想要返回更具体的409代码,以表明它是编辑冲突,as described in the spec,而不是更通用412可能由其他原因引起。这也使客户端更容易对编辑冲突进行特殊处理,因为它们会有专用的错误代码。

  • 使用 If-Match 。更好,因为我们可以使用附加到它的任何数据,但是规范再次要求使用412,尽管409更适合我们的情况。此外,规范建议If-Match与Etags相关联,我们不会将Etags用于我们的数据,因为为每条记录计算正确的Etag是不可行的。我们将标记作为记录数据的一部分用于检查,但它不作为ETag发送,现有客户端不处理ETag,因此我们不希望在可能的情况下将这一新要求强加给客户端。

  • 使用自定义X-Header。这样可以正常工作,客户可以很容易地添加,但如果可能的话,我们更愿意使用标准REST方法。

那么,在这种情况下推荐的方式是什么?有没有办法使用标准的REST方法,用409响应并让它一切都干净整洁?

1 个答案:

答案 0 :(得分:9)

基本上,如果标头中有If-*个前提条件,则必须返回412。即使您使用自定义X-Header,也只表示标头没有定义,表示必须返回412。如果自定义标头用作前提条件,则应根据其定义返回412

  

此响应代码允许客户端在当前资源元信息(标题字段数据)上放置先决条件......

E-Tag通常仅作为If-*先决条件的一部分在请求中发送,因此如果您需要409,则不会使用E-Tag

如果要使用409,只需将前提条件或后置条件放在请求正文中,而不是标题中。条件失败时,WebDav返回403409409当客户端可能能够修复请求时。 See RFC 3259

因此,总结一下:如果您的前置条件位于标题中,请使用412,否则请使用409