18

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

问题是如何发送冲突检查标签(很可能是时间戳,但我们不想强制这样做)以及如何返回错误。

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

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

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

  • 使用自定义 X-Header。这可以很好地工作,并且客户端可以很容易地添加,但如果可能的话,我们更喜欢使用标准的 REST 方法。

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

4

1 回答 1

15

基本上,如果If-*标题中有前提条件,则必须返回412. 即使您使用自定义X-Header,它也只意味着标头没有定义,它说它必须返回412。如果使用自定义头部作为前置条件,则应412根据其定义返回:

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

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

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

因此,总结一下:412如果您的先决条件在标题中,则使用,否则使用409.

于 2013-06-12T23:30:29.940 回答