SpringCloudGateway Nacos+Knife4j api接口聚合
1. 使用背景
在微服务体系下,服务划分粒度的细致,导致多个微服务模块。在开发过程中,开发负责的模块不同,存在多个模块间的业务隔离,如果存在依赖关系,在各个模块做设计时能够更好的对依赖服务更好的了解,增加各个模块之间的了解。基于以上原因,需要对微服务的api统一的展示入口。
2. Gateway 聚合api接口
gateway版本:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.0.6</version>
</dependency>
springCloud是aliba,版本为:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
Knife4j版本:
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
2.1 gateway 代码设计
gateway网关lB的策略是根据Nacos注册的服务名进行负载的,访问url形式如下:http://gatewayHost:gatewayPort/serviceName/api
增加SwaggerResourceConfig,主要用于SwaggerResource资源的获取,Knife4j UI调用接口http://localhost:8082/swagger-resources 获取,数据返回格式如下:
{
"name": "paas-account", /分组名
"url": "/paas-account/test/v3/api-docs", /获取sagger 接口文档原始数据
"location": "/paas-account/test/v3/api-docs"
}
特别说明:
url:/paas-account/test/v3/api-docs 采用/serviceName/servletContextUrl/v3/api-docs
SwaggerResource资源配置:
SwaggerResourceConfig对应代码如下
@Configuration
//在网关处控制开关
@ConditionalOnProperty(prefix = "gateway", name = "api-aggregation.enabled", havingValue = "true", matchIfMissing = false)
@Primary
public class SwaggerResourceConfig implements SwaggerResourcesProvider {
@Autowired
private RouteLocator routeLocator;
// 网关应用名称
@Value("${spring.application.name}")
private String applicationName;
//接口地址 使用的是对应的swagger 版本3
private static final String API_URI = "/v3/api-docs";
@Override
public List<SwaggerResource> get() {
//接口资源列表
List<SwaggerResource> resources = new ArrayList<>();
//服务名称列表
List<String> routeHosts = new ArrayList<>();
// 获取所有可用的应用名称
routeLocator.getRoutes()
.filter(route -> route.getUri().getHost() != null)
.filter(route -> !applicationName.equals(route.getUri().getHost()))
.subscribe(route -> {
String host ;
String basePath = null;
Map<String, Object> metadata = route.getMetadata();
if (!CollectionUtils.isEmpty(metadata)) {
//nacos 中metadata中注册时上报的servletContext,为了能够在返回SwaggerResource 界面访问api信息时。
basePath = (String) metadata.get(NacosMetaEnums.CONTEXT_PATH.getKey());
}
host = StringUtils.hasLength(basePath) ? route.getUri().getHost() + basePath:route.getUri().getHost();
routeHosts.add(host);
});
// 去重,多负载服务只添加一次
Set<String> existsServer = new HashSet<>();
routeHosts.forEach(host -> {
// 拼接url
String url = "/" + host + API_URI;
//不存在则添加
if (!existsServer.contains(url)) {
existsServer.add(url);
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setUrl(url);
swaggerResource.setName(host.split("/")[0]);
resources.add(swaggerResource);
}
});
return resources;
}
}
3. 效果
使用场景:
一个SpringCloudGateway 两个微服务网关,两个微服务名paas-account,paas-alert
Gateway knife4j界面如下:
在调试的时候需要手动添加服务名,也可以修改knife4j UI界面