PUT POST是幂等的(REST)

g_b*_*g_b 8 rest post http put idempotent

我不太明白HTTP谓词是如何被定义为幂等的.我读过的只是GET和PUT是幂等的.POST不是幂等的.但是您可以使用POST创建一个REST API,它不会更改任何内容(例如在数据库中),或者为PUT创建一个每次调用时都会更改的REST API.

当然,这可能是错误的做事方式,但如果可以做到,为什么PUT在实施时被标记为幂等(或POST为非)?我不是在挑战这个想法,我可能会错过一些东西而且我要求清除我的理解.

编辑:

我想提出一个问题的方法是:如果我使用PUT进行非幂等调用而POST这样做会有什么问题?

iva*_*sim 6

你是正确的指出HTTP协议中没有固有的强制方法/动词的幂等属性,如PUTDELETE.作为无状态协议的 HTTP不保留用户发出的每个请求的信息或状态; 每个请求都被视为独立的.

引用Wikipedia关于HTTP方法幂等属性(强调我的):

请注意,协议或Web服务器不强制执行方法是否是幂等的.完全可以编写一个Web应用程序,其中(例如)GET或其他请求触发数据库插入或其他非幂等操作.但是,如果用户代理假定重复相同的请求是安全的,则忽略此建议可能会导致不良后果.

所以,是的,它可能偏离传统的实现,并推出诸如不变的POST实现,非幂等PUT等可能没有重大的,危及生命的技术问题.但是,您可能会冒险让其他消费您的Web服务的程序员感到不安,并认为您不知道自己在做什么.

这是RFC2616关于HTTP方法安全的重要引用(强调我的):

实施者应该意识到软件代表用户在互联网上的交互,并且应该小心地让用户知道他们可能采取的任何可能对他们自己或他人有意想不到的意义的行为.

特别是,已经建立了这样的惯例:GET和HEAD方法不应该具有采取除检索之外的动作的重要性.这些方法应该被认为是"安全的".这允许用户代理以特殊方式表示其他方法,例如POST,PUT和DELETE,以便使用户意识到正在请求可能不安全的操作.

当然,不可能确保服务器不会因执行GET请求而产生副作用; 实际上,一些动态资源会考虑这个功能.这里的重要区别是用户没有请求副作用,因此不能对他们负责.

更新:正如Julian所指出的,RFC 2616已被RFC 7231取代.这是相应的部分.

因此,当您将Web服务作为PUT方法发布时,我提交的请求如下所示:

PUT /users/<new_id> HTTP/1.1
Host: example.com
Run Code Online (Sandbox Code Playgroud)

我期望创建一个新的用户资源.同样,如果我的请求如下:

PUT /users/<existing_id> HTTP/1.1
Host: example.com
Run Code Online (Sandbox Code Playgroud)

我希望更新相应的现有用户.如果我通过多次提交表单重复相同的请求,请不要弹出警告对话框(因为我喜欢既定的约定).

相反,作为POST Web服务的消费者,我会期待以下请求:

POST /users/<existing_id> HTTP/1.1
Host: example.com
Run Code Online (Sandbox Code Playgroud)

更新相应的现有用户,而请求看起来像:

POST /users/<new_id> HTTP/1.1
Host: example.com
Run Code Online (Sandbox Code Playgroud)

由于URL尚不存在而引发错误.

  • RFC 2616已经过时; 您可能想阅读RFC 7231. (2认同)