微服务集群下的前端接口层优化适配
# 场景问题
近期在做项目时,遇到了项目里的多个专题模块,对应不同的后端服务地址,因为现在后端采用了微服务的模式来部署项目,所以这样也就导致了前端在获取数据时,会去请求多个后端服务地址,为了适配后端微服务模式下的部署方式,那么前端需要针对统一接口层进行适配处理。
# 结果展示
通过上面的示例,可以看到对于不同的专题模块,实现了请求不同的后端服务地址,从而获取到数据。
# 解决方案
- 方案一: 粗暴方式 直接将服务地址拼接在相对接口请求地址上,如下所示:
// BaseService.ts
export default abstract class BaseService {
public server = commonSetting.server;
// do something
}
1
2
3
4
5
6
7
2
3
4
5
6
7
// DemoService.ts
export default class DemoService extends CommonService {
@serviceHandler("query", { title: "获取区域评估数据" })
public async getInfos(): Promise<any> {
return this._get<any>(`${this.server}/unity/evaluate-warning/area-evaluate`);
}
@serviceHandler("query", { title: "分区域统计数据" })
public async getRegions(): Promise<any> {
return this._get<any>(`${this.server}/unity/evaluate-warning/indicator-evaluate/reigon`);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
* 优点:快捷,清晰
* 缺点:扩展性较差,不利于后期模块移植
- 方案二:“摸鱼”模式
通过继承的方式,动态覆盖更新baseUrl,从而实现最小化改动接口层,扩展性也相应更加灵活了,如下所示:
export default abstract class BaseService {
/**
* @description 升级改造,适配多后端服务地址
* @author wanghaifeng
* @date 2020.10.23 14:08
* @type {string}
* @memberof BaseService
*/
public baseUrl: string = commonSetting.baseUrl;
protected url(url: string): string {
return this.baseUrl + url;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
而 实际专题模块接口请求层,可以这样实现:
/**
* 服务中心-后端接口服务基础
*/
export default class ServeCenterService extends CommonService {
// 配置服务中心后端服务地址
public baseUrl: string = commonSetting.serviceCenterUrl;
// 获取目录
public getCatalogs(params?: any) {
return this._get<any>("/unity/server/category/tree/no-action/", { params: { ...params } });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
服务中心专题子模块接口层,便可以直接继承 ServeCenterService.ts, 从而达到 接口请求地址保持相对地址,利于后期扩展移植处理。栗子:
export default class MarketService extends ServeCenterService {
@serviceHandler("query", { title: "查询服务列表" })
public page(params?: any) {
return this._post<any>("/unity/server/action/page", params);
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
两种实现方式对比如下:
# 小结
其实两种方案实现的思想,是一样的,不同的是,一个是通过覆盖更新默认服务地址动态更新,实际接口请求地址保持相对地址,而另一个是通过声明一个新的变量,并注入到基础服务里,最后在实际接口请求中做拼接处理。这两种方式的实现适配后端微服务部署方式,都是可以做到的,但考虑到后期扩展和移植,个人更倾向于方案二的实现方式,如果大家有更好的解决方案,可以拿出来 show 一波,跟我们分享分享。