在实现RestFul服务中,为什么HTTP方法PUT应该是幂等而不是POST?

Sam*_*Sam 6 java rest jax-rs

互联网上有许多资源可供使用,其中讨论了PUT与POST。但是我不明白这将如何影响在RestFul服务下完成的Java实现或后端实现?我提到的链接如下所述:

https://www.keycdn.com/support/put-vs-post/

https://spring.io/understanding/REST#post

https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

http://javarevisited.blogspot.com/2016/10/difference-between-put-and-post-in-restful-web-service.html

例如,假设有一个针对地址的RestFul Web服务。因此,POST /addresses将完成更新地址PUT /addresses/1的工作,并完成创建地址的工作。现在,HTTP方法PUT和POST如何控制后台服务代码在做什么?

PUT /addresses/1 
Run Code Online (Sandbox Code Playgroud)

可能最终在数据库中创建相同地址的多个条目。

所以我的问题是,幂等行为为什么链接到HTTP方法?

您将如何使用指定的HTTP方法控制幂等行为?还是只是建议准则或标准做法?

我不是在寻找什么是幂等行为的解释,但是是什么使我们标记这些HTTP方法呢?

Dan*_*zek 5

这是特定于 HTTP 的。由于您链接的 RFC 指出https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html(请参阅本答案底部的最新 RFC 链接)。它没有被描述为 REST 的一部分:https : //www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

现在你写道,

我不是在寻找什么是幂等行为的解释,而是什么让我们如此标记这些 HTTP 方法?

幂等操作总是有相同的结果(我知道你知道),但结果与 HTTP 响应不同。从 HTTP 的角度来看,使用任何方法的多个请求甚至所有相同的参数都可能有不同的响应(即时间戳),这应该是显而易见的。所以它们实际上可以不同。

不应该改变的是操作的结果。因此多次调用PUT /addresses/1 不应创建多个地址。

如您所见,它被称为 PUT not CREATE 是有原因的。如果资源不存在,它可能会创建资源。如果它存在,那么它可能会用新版本(更新)覆盖它,如果它完全相同应该在服务器上不做任何事情并导致相同的答案,就好像它是相同的请求一样(因为它可能是相同的请求重复,因为之前的请求被中断,客户端没有收到响应)。

与 SQL PUT 相比,INSERT OR UPDATE不仅INSERTUPDATE.

所以我的问题是,为什么幂等行为与 HTTP 方法相关联?

它类似于 HTTP 方法,因此某些服务(代理)知道,在请求失败的情况下,它们可以安全地尝试(不是在安全 HTTP 方法方面,而是在幂等方面)重复它们。

您将如何通过使用特定的 HTTP 方法来控制幂等行为?

我不确定你要什么。但:

  • GET, HEAD 只返回数据它不会改变任何东西(除了一些日志、统计数据、元数据?)所以它是安全和幂等的。
  • POST、PATCH 可以做任何既不安全也不幂等的事情
  • PUT、DELETE - 不安全(它们更改数据)但它们是幂等的,因此重复它们是“安全的”。

这基本上意味着可以通过代理、缓存、网络爬虫等安全地创建安全方法,而无需更改任何内容。幂等可以通过软件重复,并且不会改变结果。

或者这只是建议的指南或标准做法?

这是“标准”。也许 RFC 还不是标准,但它最终会成为一个标准,我们没有其他可以(也应该)遵循的东西。

编辑:

由于上面提到的 RFC 已经过时,这里有一些关于该主题的当前 RFC 的参考:

感谢Roman Vottner的建议。

  • 请使用最新版本的 HTTP 1.1 规范:[消息语法和路由](https://tools.ietf.org/html/rfc7230)、[语义和内容](https://tools.ietf.org /html/rfc7231)、[条件请求](https://tools.ietf.org/html/rfc7232)、[范围请求](https://tools.ietf.org/html/rfc7233)、[缓存]( https://tools.ietf.org/html/rfc7234), [身份验证](https://tools.ietf.org/html/rfc7235) (2认同)