Http请求的幂等性

对 HTTP 协议的使用实际上存在着两种不同的方式:一种是 RESTful 的,它把 HTTP 当成应用层协议,比较忠实地遵守了 HTTP 协议的各种规定;另一种是 SOA 的,它并没有完全把HTTP 当成应用层协议,而是把 HTTP 协议作为了传输层协议,然后在 HTTP 之上建立了自己的应用层协议。这里所讨论的 HTTP 幂等性主要针对 RESTful 风格的,但幂等性并不属于特定的协议,它是分布式系统的一种特性;所以,不论是 SOA 还是 RESTful 的 Web API 设计都应该考虑幂等性。下面将介绍 HTTP GET、DELETE、PUT、POST 四种主要方法的语义和幂等性。

GET

HTTP GET 方法用于获取资源,不应有副作用,所以是幂等的。

比如:GET http://www.bank.com/account/123456,不会改变资源的状态,不论调用一次还是 N 次都没有副作用。请注意,这里强调的是一次和 N 次具有相同的副作用,而不是每次GET 的结果相同。 GET http://www.news.com/latest-news 这个 HTTP 请求可能会每次得到不同的结果,但它本身并没有产生任何副作用,因而是满足幂等性的。

DELETE

HTTP DELETE 方法用于删除资源,有副作用,但它应该满足幂等性。

比如:DELETE http://www.forum.com/article/4231调用一次和 N 次对系统产生的副作用是相同的(重复删除也不会引起错误),即删掉 id 为 4231 的帖子;因此,调用者可以多次调用或刷新页面而不必担心引起错误。

POST & PUT

比较容易混淆的是 HTTP POST 和 PUT。POST 和 PUT 的区别容易被简单地误认为“POST 表示创建资源,PUT 表示更新资源”;而实际上,二者均可用于创建资源,更为本质的差别是在幂等性方面。在 HTTP 规范中对 POST 和 PUT 是这样定义的:POST 所对应的 URI 并非创建的资源本身,而是资源的接收者。比如:POST http://www.forum.com/articles 的语义是在 http://www.forum.com/articles 下创建一篇帖子,HTTP 响应中应包含帖子的创建状态以及帖子的 URI。两次相同的 POST 请求会在服务器端创建两份资源,它们具有不同的 URI;所以,POST 方法不具备幂等性。而 PUT 所对应的 URI 是要创建或更新的资源本身。比如:PUT http://www.forum/articles/4231 的语义是创建或更新 ID 为 4231 的帖子。对同一 URI 进行多次 PUT 的副作用和一次 PUT 是相同的;因此,PUT 方法具有幂等性。

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/http%e8%af%b7%e6%b1%82%e7%9a%84%e5%b9%82%e7%ad%89%e6%80%a7/