幂等性本来是数学中的含义,表达式的是N次变换与1次变换的结果相同。
而RESTFul API中的幂等性是指调用某个方法1次或N次对资源产生的影响结果都是相同的,须要特别注意的是:这里幂等性指的是对资源产生的影响结果,而不是调用HTTP方法的返回结果。
举个例子,RESTFul API中的GET方法是查询资源信息,不会对资源产生影响,因此它是符合幂等性的,可是每次调用GET方法返回的结果有可能不一样(可能资源的某个属性在调用GET方法以前已经被其余方法修改了)。
实际上,在分布式架构中的API幂等性不只仅针对RESTFul接口,而是对全部类型的接口适用,目的是为了确保调用1次或N次接口时对资源的影响结果都是相同的。html
接口的幂等性确保了不管调用1次仍是N次对资源的影响都是相同的,这在某些场合下是很是有用的。
举个例子,有这样一个接口方法:pay(long account, int money),该方法用于银行卡扣款支付,参数account为帐户ID,money为须要扣除的钱数。当用户从网页上点击支付按钮时,在该方法的实现逻辑中须要从指定帐户中扣除对应的商品价钱。若是支付操做已经成功执行,可是响应消息由于某种缘由未能及时返回给客户端,这时候给用户的体验是多是未支付成功,若是此时再次点击支付按钮,那么将再一次执行该方法,结果可能会致使用户只买了一件商品却花了双份的钱,这固然是不合理的。整个流程以下图所示:
git
固然,就上述例子的场景,为了不用户重复支付,是能够经过别的方式解决的,好比:分布式事务,或者根据支付状态提示给予用户进行提示等等。
可是,若是引入了分布式事务,那么将带来实现上的复杂性,并且会影响到接口性能;而采起提示信息的方式并不能百分之百确保用户不会重复支付,存在必定的风险。而若是接口符合幂等性,即:对同一个订单不管是执行一次支付仍是屡次支付,在服务端都确保只会扣一次款,那么既不须要引入分布式事务的复杂性,也能从根本上解决重复支付的问题,这也就是接口符合幂等性的价值所在。github
总而言之,接口符合幂等性在能够下降系统实现的复杂性,并能保证资源状态的一致性。跨域
RESTFul风格的接口设计本质上使用的是HTTP协议方法,所以,RESTFul接口方法的幂等性指的就是HTTP方法的幂等性。
经常使用的HTTP方法有:OPTIONS(获取服务器信息),HEAD(请求资源首部信息),GET(获取资源),POST(建立资源),PUT(更新资源所有信息),PATCH(更新资源部分信息),DELETE(删除资源)。那么,这些HTTP方法的幂等性又是什么样的呢?
除了幂等性以外,HTTP方法的安全性是指不对资源产生修改。
以下是经常使用HTTP方法的幂等性和安全性总结:浏览器
HTTP方法名称 | 是否幂等 | 是否安全 |
---|---|---|
OPTIONS | Y | Y |
HEAD | Y | Y |
GET | Y | Y |
PUT | Y | N |
DELETE | Y | N |
POST | N | N |
PATCH | N | N |
从上述表格中能够看出,HTTP方法的幂等性和安全性并非同一个概念,以下是对个各个方法的幂等性和安全性解释:安全
设计幂等性接口的关键在于保证接口不管是被调用1次仍是N次,它对资源所产生的影响都是相同的。
从上述HTTP方法的幂等性总结中能够得知,HTTP协议的POST和PATCH方法都不是幂等性的(可是咱们却常常会在RESTFul接口中使用到它们),那是否就意味中没法将POST和PATCH方法设计为幂等性接口了呢?答案显然是否认的。在上述例子中,能够将订单ID也做为方法参数之一,如:pay(long account, int money, long order),这样在服务端确保一个订单只会被支付一次(订单号是全局惟一的),那么不管该方法被调用1次仍是N次结果都是同样的,也就保证了接口的幂等性。固然,在哪些没有订单号的场景,能够为接口操做生成一个全局惟一的处理号ID,并把该处理号ID做为方法参数之一,这样在服务端确保一个处理号ID只会被执行一次就保证了接口的幂等性。
符合幂等性的接口调用流程描述以下图所示:
服务器
虽说设计符合幂等性的接口在某些场合能够下降系统的复杂性(如:能够不用引入分布式事务),可是并不是在全部场合的问题都能经过幂等性接口解决,在必要的时候依然须要引入分布式事务处理这样的框架。咱们不要也不能把接口幂等性做为万能的解决办法,可是,咱们在设计接口时尽可能考虑符合幂等性处理是很是有价值的。restful
【参考】
http://blog.720ui.com/2016/restful_idempotent/ 如何理解RESTful的幂等性
https://www.cnblogs.com/weidagang2046/archive/2011/06/04/idempotence.html 理解HTTP幂等性
https://sofish.github.io/restcookbook/http%20methods/idempotency/ RESTful 手册架构