幂等性的含义和 HTTP请求方法的幂等性
1、什么是幂等性
===============
幂等性,英文是idempotent,读作[aɪ'dɛmpətənt]。
它的含义如下:
“Methods can also have the property of "idempotence" in that the side-effects of N > 0 identical requests is the same as for a single request.”(这句话翻译过来是这样的:方法可以有幂等性,幂等性指的是N>0次的完全相同的请求的副作用和一次单个请求的副作用是相同的)。
即,如果一个方法重复执行多次,产生的效果是一样的,那么这个方法就是幂等的。
2、HTTP请求方法的幂等性
=====================
方法名 | 作用 | 安全性 | 幂等性 |
DELETE | 删除资源,幂等操作 | 否 | 是 |
POST | 新增资源,非幂等操作 | 否 | 否 |
GET | 查询资源,幂等操作 | 是 | 是 |
PUT | 更新资源,幂等操作 | 否 | 是 |
PATCH | 更新资源,非幂等操作 | 否 | 否 |
HEAD | 类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头 | 是 | 是 |
OPTIONS | 用于客户端查看服务器的性能 | 是 | 是 |
3、请求方法的语义辨析
===================
3.1 put和post的区别
------------------------------
有的观点认为,应该用POST来创建一个资源,用PUT来更新一个资源;有的观点认为,应该用PUT来创建一个资源,用POST来更新一个资源;还有的观点认为可以用PUT和POST中任何一个来做创建或者更新一个资源。这些观点都只看到了风格,争论起来也只是争论哪种风格更好,其实,用PUT还是POST,不是看这是创建还是更新资源的动作,这不是风格的问题,而是语义的问题。
在HTTP中,PUT被定义为idempotent的方法,而POST则不是幂等的,这是一个它们在语义上的最重要的区别。
举一个例子,假如有一个博客系统提供一个Restful API,模式是这样http://superblogging/blogs/{blog-name}。当往这个URI发送一个HTTP PUT或者POST请求时,博文会存放在http request body部分发送给服务器端。
此时,这个请求应该用PUT方法还是POST方法呢?这取决于这个REST服务的行为是否是幂等的。
假如客户端发送两个http://superblogging/blogs/Sample请求,服务器端产生了两个文章内容一样的博客,那就说明这个服务不是幂等的,因为多次调用产生了多个结果,而不是多次调用只产生一个结果。
如果第二个请求把第一个请求给覆盖掉了,那这个服务就是幂等的。
前一种情况,应该使用POST方法,后一种情况,应该使用PUT方法。
3.2 为什么patch是非幂等的
-------------------------------------
PUT方法的实体无结构的,它直接把实体部分的数据替换到服务器的资源上。而PATCH提供的实体则需要根据程序或其它协议的定义,解析后在服务器上执行,以此来修改服务器上的数据。也就是说,PATCH请求是会执行某个程序的,如果重复提交,程序可能执行多次,对服务器上的资源就可能造成额外的影响,这就可以解释它为什么是不幂等的了。
举个例子,如果服务器上有个资源/abc.int,里面存放一个整数,值为 1。当GET这个资源的时候,服务器响应的实体只包含了 1 这个数字。现在在自己的框架中定义当提交PATCH请求,实体匹配^+d+$的格式时就对服务器资源中的数字执行一个加法操作。于是当客户端向/abc.int地址发起PATCH请求,实体部分为+3之后,服务器的/abc.int资源中的数据就变成 4,也就是说,GET它会得到 4。如果客户端不小心重复提交了PATCH请求,那么+3就会被再执行一次,这个资源的数据就变成 7。从这个例子可以看出,PATCH请求会对资源进行修改,请求一次修改一次,多次请求多次修改,每次修改之后资源的状态都会改变,这就是为什么说PATCH方法是非幂等的了。
参考资料
1、http://www.cnblogs.com/jinks/p/3511282.html http请求方法的安全性和幂等性
2、http://www.cnblogs.com/yin-jingyu/archive/2011/08/01/2123548.html http协议的说明
3、http://www.jianshu.com/p/178da1e2903c