API 网关模式
标签
- 云分布式
- 解耦
- 微服务
目的
在单个位置聚合对微服务的多个调用,用户只需要对Api网关调用一次,由网关再对各个微服务发起调用。
解释
在微服务时代,一个表单的展示往往需要多个服务的结果,相应的缺点也就显露出来了:
- 如果客户端分别调用每个微服务的则会非常耗时
- 如果涉及的服务发生了变化,则每个使用这个服务的客户端都需要变更
因此为了解决这些问题,则在服务和客户端之间增加了一层,也就是API网关,由网关对客户端所需要调用的服务进行聚合,客户端只需要调用一次网关,剩下的只需要交给网关去调用涉及的微服务即可。
维基百科
API网关就像是前端服务,用于接收前端请求,设置和执行安全策略,将请求转发给后端服务和将响应回复给客户端。API网关可以提供一些数据分析和收集的功能(日志),还有一些缓存的功能,并且可以对认证、鉴权、安全、审计、合规性校验进行功能支撑。
实战
假设我们的开发的程序有桌面端和手机端两种,商品的浏览界面在桌面端需要展示价格和对应的商品图片,而在手机端则只需要展示商品的价格即可,对应的分别为价格服务和图片服务两个微服务。
如果没有API网关,则客户端需要分配对两种客户端型号做适配,是否调用两个服务,两个服务的地址又是什么;而如果有API网关,则客户端则只需要根据不通的客户端类型调用不同的接口即可,或者传参不同而已,具体的调用逻辑交给网关去做即可。
//图片服务客户端
public interface ImageClient {
String getImagePath() ;
}
public class ImageClientImpl implements ImageClient{
public String getImagePath() {
HttpResponse response = HttpRequest.get("http://localhost:50005/image-path").execute();
if (response.isOk()) {
return response.body();
}
return null;
}
}
//价格服务客户端
public interface PriceClient {
String getPrice();
}
public class PriceClientImpl implements PriceClient{
public String getPrice() {
HttpResponse response = HttpRequest.get("http://localhost:50006/price").execute();
if (response.isOk()) {
return response.body();
}
return null;
}
}
//桌面产品实体
class DesktopProduct {
private String imagePath;
private String price;
}
//手机端产品实体
public class MobileProduct {
private String price;
}
//API网关
public class ApiGateway {
@Autowired
private ImageClient imageClient;
@Autowired
private PriceClient priceClient;
@RequestMapping(path = "/desktop", method = RequestMethod.GET)
public DesktopProduct getProductDesktop() {
DesktopProduct desktopProduct = new DesktopProduct();
desktopProduct.setPrice(priceClient.getPrice());
desktopProduct.setImagePath(imageClient.getImagePath());
return desktopProduct;
}
@RequestMapping(path = "/mobile", method = RequestMethod.GET)
public MobileProduct getProductMobile() {
MobileProduct mobileProduct = new MobileProduct();
mobileProduct.setPrice(priceClient.getPrice());
return mobileProduct;
}
}
参考
- Java Design Patterns