【问题标题】:PUT vs POST - correct response code if already completedPUT 与 POST - 如果已经完成则正确的响应代码
【发布时间】:2023-02-17 02:47:44
【问题描述】:
目前正在开发一个 REST API,它有一套端点函数可以更新特定资源的“状态”。
我正在使用 POST 创建初始资源,然后使用 PUT 更新状态 - PUT 是要使用的正确方法吗?
状态更新被记录在日志中,因此为了避免有人多次使用相同的值更新状态,我希望在其中放置一些业务逻辑以避免重复输入相同的状态。如果有人试图调用同一个函数两次,比如说“CancelResource()”——我应该在第二次调用时返回 200 成功,而不进行更新,还是发送某种错误响应会更好?
我正在考虑返回一个 405“不允许的方法”,但这感觉有点残酷的.我也不知道 200 对客户是否非常有用。
【问题讨论】:
标签:
rest
http-post
http-status-codes
http-put
【解决方案1】:
PUT适合更新,PUT应该是幂等的。这意味着如果你连续两次执行完全相同的PUT请求,服务器状态应该与你只执行一次没有什么不同。
这在例如不可靠的连接中很有用。如果失败,客户端可以重复请求,而不必担心服务器以某种方式接收并处理了请求。
因此,如果您有办法检测相同的请求,则忽略第二个请求并在两个请求上返回 200 OK,这是处理此问题的绝佳方法。
【解决方案2】:
PUT 是要使用的正确方法吗?
如果请求的主体被提议作为目标资源的替代表示,则 PUT 是合适的。
给定表示的成功 PUT 表明对同一目标资源的后续 GET 将导致在 200 (OK) 响应中发送等效表示。 -- RFC 9110
想想“保存文件”——如果我们试图将内容上传到 Web 服务器,PUT 是我们将使用的 HTTP 方法。
我是否应该在第二次调用时返回 200 成功,而不是进行更新,
大概。对于 2xx 与 4xx,您应该考虑状态代码对所涉及的缓存的影响。参见RFC 9111。
请注意,RFC 9110 在 If-Match 条件标头的讨论中特别提到了这个选择:
如果请求是一个似乎已经应用到所选表示的状态更改操作,则源服务器可以用 2xx(成功)状态代码进行响应(即,用户代理请求的更改已经成功,但是用户代理可能不知道它,可能是因为先前的响应丢失或其他用户代理进行了等效更改)。
【解决方案3】:
PUT 是幂等的,拒绝 PUT 请求没有意义,因为什么都没有改变。只需发送 200 ok 并且不要更改任何内容。