解耦,未解耦的区别
HTTP中的幂等性意味着相同的请求可以执行多次,效果与仅执行一次一样。 如果用新资源替换某个资源的当前状态,则无论您执行多少次,最终状态都将与您仅执行一次相同。 举一个更具体的例子:删除用户是幂等的,因为无论您通过唯一标识符删除给定用户多少次,最终该用户都会被删除。 另一方面,创建新用户不是幂等的,因为两次请求该操作将创建两个用户。 用HTTP术语来说是RFC 2616:9.1.2等幂方法必须说的:
9.1.2等幂方法
方法还可以具有“ 幂等 ”的特性,因为[…] N> 0个相同请求的副作用与单个请求的副作用相同。 GET,HEAD,PUT和DELETE方法共享此属性。 同样,方法OPTIONS和TRACE不应有副作用,因此本质上是幂等的。
时间耦合是系统的不良特性,其中正确的行为隐含地取决于时间维度。 用简单的英语来说,这可能意味着例如系统仅在所有组件同时存在时才起作用。 阻塞请求-响应通信(ReST,SOAP或任何其他形式的RPC)要求客户端和服务器同时可用,这就是这种效果的一个示例。
基本了解这些概念的含义后,我们来看一个简单的案例研究- 大型多人在线角色扮演游戏 。 我们的人工用例如下:玩家发送优质短信,以在游戏内购买虚拟剑。 交付SMS时将调用我们的HTTP网关,我们需要通知部署在另一台计算机上的InventoryService
。 当前的API涉及ReST,其外观如下:
@Slf4j
@RestController
class SmsController {
private final RestOperations restOperations;
@Autowired
public SmsController(RestOperations restOperations) {
this.restOperations = restOperations;
}
@RequestMapping(value = "/sms/{phoneNumber}", method = POST)
public void handleSms(@PathVariable String phoneNumber) {
Optional<Player> maybePlayer = phoneNumberToPlayer(phoneNumber);
maybePlayer
.map(Player::getId)
.map(this::purchaseSword)
.orElseThrow(() -> new IllegalArgumentException("Unknown player for phone number " + phoneNumber));
}
private long purchaseSword(long playerId) {
Sword sword = new Sword();
HttpEntity<String> entity = new HttpEntity<>(sword.toJson(), jsonHeaders());
restOperations.postForObject(
"http://inventory:8080/player/{playerId}/inventory",
entity, Object.class, playerId);
return playerId;
}
private HttpHeaders jsonHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
private Optional<Player> phoneNumberToPlayer(String phoneNumber) {
//...
}
}
依次产生类似于以下内容的请求:
> POST /player/123123/inventory HTTP/1.1
> Host: inventory:8080
> Content-type: application/json
>
> {"type": "sword", "strength": 100, ...}
< HTTP/1.1 201 Created
< Content-Length: 75
< Content-Type: application/json;charset