本文原创地址,
我的博客
:https://jsbintask.cn/2019/03/21/api/restful-api-idempotent/(食用效果最佳),转载请注明出处!
前言
上一篇我们介绍了restful api
相关知识,本篇我们介绍另一个于rest息息相关的概念:幂等
;
介绍
我们知道,springcloud做微服务时,服务之间的调用,服务的暴露使用的就是restful api,现在可以考虑这么一种情况,加入我们有订单服务A,支付服务B,A向B服务发送了一次请求,但由于网络,超时等的原因,A认为B该次服务失败,于是A又发起了一次同样的请求,那么这次请求会不会有什么不良影响呢?如果B又调用了其它服务呢?
这里我们可以引出一个概念:在REST API中,当发送多个相同的请求与发送单个请求具有相同的效果时,该REST API就可以称为幂等。
所以A发送相同的请求调用B服务不会出现业务逻辑的偏差,这样B服务就是幂等的。
http method 幂等
如果你在设计API时遵循REST原则,则GET,PUT,DELETE,HEAD,OPTIONS和TRACE HTTP方法的自动幂等REST API。只有POST API不是幂等的。
POST 不是幂等的。
GET,PUT,DELETE,HEAD,OPTIONS和TRACE是幂等。
why?
POST
通常,当然不是绝对; 我们使用POST API在服务器上是为了创建新资源。所以,调用相同的POST请求N次时,您将在服务器上拥有N个新资源。因此,POST不是幂等的。
GET,HEAD,OPTIONS和TRACE
GET,HEAD,OPTIONS和TRACE方法永远不会改变服务器上的资源状态。因为它们全部用来获取数据。因此,调用多个请求将不会在服务器上进行任何写操作,所以GET,HEAD,OPTIONS和TRACE是幂等的。
PUT和PATCH
使用PUT,PATCH API来更新资源状态。调用PUT API N次,则第一个请求将更新资源; N-1请求将一次又一次地覆盖相同的资源状态 - 实际上不会改变任何东西。因此,PUT是幂等的。
DELETE
调用N个相同的DELETE请求时,第一个请求将删除资源,响应将是200 (OK)或204 (No Content)。其他N-1请求将返回404 (Not Found)。显然,响应与第一个请求不同,但服务器端的任何资源都没有状态更改,因为原始资源已被删除。因此,DELETE是幂等的。
这里值得注意的是,delete可能有这样一种设计:
DELETE /user/latest
删除最新的用户,这样的话调用N次将删除N个用户,DELETE同样不是幂等的,所以该api可以考虑设计成 POST
解决办法
通常,我们为了给所有服务都设计成幂等,有以下解决办法:
- 异步处理,利用消息中间件,A向中间件中发送一个消息,A服务直接返回成功,B服务异步消费。
- 唯一ID,每次请求都可带上唯一ID,A发送请求时,B可以知道该请求是否已经发送过,有则直接忽略。
总结
从幂等概念谈起,再结合http各method意义谈了每个方法是否幂等。 最后引出解决办法。
关注我,这里只有干货!