我不太清楚如何将HTTP谓词定义为幂等。我读过的只是GET和PUT是幂等的。 POST不是幂等的。但您可以使用POST创建一个REST API,它不会更改任何内容(例如在数据库中),或者为PUT创建一个REST API,每次调用它时都会更改。
当然,这可能是错误的做事方式,但如果可以做到,为什么PUT在实施时被标记为幂等(或POST不)?我不是在质疑这个想法,我可能会错过一些东西而且我要求清除我的理解。
我想提出一个问题的方法是:如果我使用PUT进行非幂等调用而POST会这样做会出现什么问题?
答案 0 :(得分:5)
你指出HTTP协议中没有固有的东西来强制执行PUT
和DELETE
等方法/动词的幂等属性。作为stateless protocol的HTTP不保留用户发出的每个请求的信息或状态;每个请求都被视为独立请求。
引用维基百科idempotent attribute of HTTP methods(强调我的):
请注意,方法是否是幂等的不是由强制执行的 协议或Web服务器。 写网络是完全可能的 应用程序,其中(例如)数据库插入或其他 非幂等行为由GET或其他请求触发。忽略 但是,这项建议可能会导致不良后果, 如果用户代理假定重复相同的请求是安全的 它不是。
所以是的,有可能偏离传统的实现,并推出诸如不变的POST实现,非幂等PUT等可能没有重大的,危及生命的技术问题。但是,您可能会冒着让其他程序员误用您的Web服务的风险,认为您不知道自己在做什么。
以下是RFC2616关于HTTP方法的重要引用安全(强调我的):
实施者应该知道该软件代表用户 他们在互联网上的互动,应该小心允许 用户要知道他们可能采取的任何行动 对自己或他人意想不到的重要性。
特别是,约定已经建立了GET和 HEAD方法不应该具有采取行动的意义 除了检索。这些方法应该被认为是“安全的”。 这允许用户代理表示其他方法,例如POST,PUT 和DELETE,以一种特殊的方式,,以便让用户知道 事实上,正在要求采取可能不安全的行动。
当然,无法确保服务器不能 由于执行GET请求而产生副作用;在 事实上,一些动态资源考虑了一个功能。 重要的 区别在于用户没有请求副作用,所以 因此不能对他们负责。
更新:正如Julian所指出的,RFC 2616已被RFC 7231取代。Here's the corresponding section。
因此,当您将Web服务发布为PUT
方法时,我提交的请求如下所示:
PUT /users/<new_id> HTTP/1.1
Host: example.com
我希望能够创建一个新的用户资源。同样,如果我的请求如下:
PUT /users/<existing_id> HTTP/1.1
Host: example.com
我希望更新相应的现有用户。如果我通过多次提交表单重复相同的请求,请不要弹出警告对话框(因为我喜欢既定的约定)。
相反,作为POST网络服务的消费者,我会期待以下请求:
POST /users/<existing_id> HTTP/1.1
Host: example.com
更新相应的现有用户,而请求看起来像:
POST /users/<new_id> HTTP/1.1
Host: example.com
引发错误,因为该URL尚不存在。
答案 1 :(得分:2)
实际上,实现可以做任何想做的事情。但是,如果根据协议规范不正确,可能会发生令人惊讶的事情(例如,如果第一次尝试失败,库或中间人会重复PUT)。
答案 2 :(得分:2)
希望该链接对您有所帮助:HTTP Method idempotency
在处理安全方法时要小心:如果像GET这样看似安全的方法会改变资源,那么您和服务器之间的任何中间件客户端代理系统都可能会缓存此响应。另一个想要通过相同的URL(例如:http://example.org/api/article/1234/delete)更改此资源的客户端不会调用服务器,而是直接从缓存中返回信息。任何中间件代理都不会缓存非安全(和非幂等)方法。