网关层聚合Swagger接口文档的实现思路
在介绍实现思路前,要明确项目中的接口数据是怎样被渲染到 Swagger UI
页面中的。
打开项目中某个服务端 Swagger UI
页面。打开浏览器控制台中的 “Network” 面板,在页面加载过程中查看其中的请求,Swagger UI
页面中接口文档加载主要有 3 个请求,如图 9-1 所示。其中,/swagger-resources
和 /v3/api-docs
两个请求的内容和作用对本次找出聚合 Swagger
接口文档的实现思路有一些帮助。

/swagger-resources
请求用于获取 Swagger
资源,其响应的内容是 Swagger
资源数组。图 9-1 中返回的资源列表只有一个,资源名称为 default
,资源网址为当前项目的基础路径加上 /v3/api-docs
。获取 Swagger
资源后,直接请求这个资源网址获取接口文档的 JSON
数据,如图 9-2 所示。

获取这些接口数据后,就可以渲染到 Swagger UI
页面中了。
好的,Swagger UI
页面中接口文档的加载过程清晰了,步骤如下:获取页面配置→获取 Swagger
资源→根据资源 URL
获取接口文档的 JSON
数据→将接口文档的 JSON
数据渲染到页面中。
聚合 Swagger
接口文档的实现思路就是在 “获取 Swagger 资源” 这个步骤中做一些修改,让当前的 Swagger UI
页面可以获取多个 Swagger
资源。具体做法是在网关层整合 Swagger
之后,从路由配置中获取底层多个微服务实例信息,根据这些实例信息组装对应的 Swagger
页面所需的资源信息,包括资源名称、资源 URL
等。
讲完了实现思路就要来聊一聊具体的编码实现,对于 Swagger
资源处理,Swagger
底层提供了一个 SwaggerResourcesProvider
接口,这是资源处理的关键接口,其唯一的默认实现类是 springfox.documentation.swagger.web.InMemorySwaggerResourcesProvider
,在默认的情况下接口资源都会经由此类处理后返回给前端。其核心代码如下:
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
for (Map.Entry<String, Documentation> entry : documentationCache.all().entrySet()) {
String swaggerGroup = entry.getKey();
if (swagger1Available) {
SwaggerResource swaggerResource = resource(swaggerGroup, swagger1Url);
swaggerResource.setSwaggerVersion("1.2");
resources.add(swaggerResource);
}
if (swagger2Available) {
SwaggerResource swaggerResource = resource(swaggerGroup, swagger2Url);
swaggerResource.setSwaggerVersion("2.0");
resources.add(swaggerResource);
}
if (oas3Available) {
SwaggerResource swaggerResource = resource(swaggerGroup, oas3Url);
swaggerResource.setSwaggerVersion("3.0.3");
resources.add(swaggerResource);
}
}
Collections.sort(resources);
return resources;
}
private SwaggerResource resource(
String swaggerGroup,
String baseUrl) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(swaggerGroup);
swaggerResource.setUrl(swaggerLocation(baseUrl, swaggerGroup));
return swaggerResource;
}
至此,网关聚合的实现就清晰了。在网关层加入 Swagger
依赖并重写 SwaggerResourcesProvider
接口中的 get()
方法,将需要聚合路由的子模块 Swagger
资源组装成 SwaggerResource
对象并形成数据集合,这样就可以在 Swagger UI
页面中选择对应的服务模块,调用不同服务中的 /v3/api-docs
,获取具体的接口资源并展示到网关层的 Swagger UI
页面中。