检测 REST PUT 操作何时收到对象的陈旧或旧版本的最佳实践[关闭]

问题描述 投票:0回答:1

我了解在 REST 中,PUT 操作完全更新服务器上的对象/记录。似乎一个常见的问题是如下场景:

  1. Bob 对一个对象发出 GET 请求。对于这个例子,假设它是一个不完整/几乎过期的文档,Bob 是一名经理,他可能正式将文档标记为“过期”。
  2. Alice 对同一文档发出 GET 请求。
  3. Alice 完成文档并通过 PUT 调用在服务器上更新它。
  4. Bob 进行 PUT 调用,更新文档。这将覆盖 Alice 的新工作。更糟糕的是,Bob 添加了仅适用于旧版本的注释,并且可能已将此版本标记为正式过期。

似乎应该有一个标准的做法来拒绝步骤 4 中的 PUT 调用,方法是指示 PUT 请求正在更新对象的陈旧版本。这可以通过在“GET”操作期间在接收到的对象上包含时间戳或版本来完成。 (时间戳或版本只需要指示服务器提供的最后编辑版本 - 例如,指示检索时间的时间戳将打破幂等规则。客户端永远不会更新此时间戳/版本也很重要PUT 调用,否则 Bob 仍然可以不公正地覆盖 Alice 的文档。)

但是提供对象的版本似乎并不是 GET/PUT REST 调用的标准做法。忽略像这样的潜在冲突实际上是 REST 中的常见做法,还是有一种既定的模式来确保 Bob 不会不公正地拒绝和覆盖 Alice 的文档?

谢谢!

编辑:答案是在 RFC 9110 中。基本上第 4 步可以通过使用“If-Match”标头字段或类似字段来保护:

https://www.rfc-editor.org/rfc/rfc9110.html#field.if-match:~:text=If%2DMatch%20is,Match%20field%20value.

If-Match 最常与状态更改方法(例如,POST、PUT、DELETE)一起使用,以防止多个用户代理可能在同一资源上并行操作时意外覆盖(即,防止“丢失更新”问题).通常,如果所选表示的当前实体标签不是 If-Match 字段值中的成员,它可以与涉及选择或修改表示的任何方法一起使用以中止请求。

此外,对于我们这些使用 Spring 的人来说,可以添加一个简单的注释来自动支持 If-Match 验证:

https://docs.spring.io/spring-data/rest/docs/current/reference/html/#conditional.etag

spring rest http-headers put etag
1个回答
1
投票

似乎应该有一个标准的做法来拒绝步骤 4 中的 PUT 调用,通过指示 PUT 请求正在更新对象的陈旧版本。

好消息:我们有一个。

它显示为两个部分;在包含我们资源表示的响应中,我们包括特定于表示的验证器字段

在修改资源的请求中,我们使用 条件请求 - 我们在请求中使用标准化字段(也称为标头)来标识我们试图替换的版本。

根据资源的当前状态,服务器然后要么正常处理请求,要么返回 412 Precondition Failed 响应。

© www.soinside.com 2019 - 2024. All rights reserved.