导入 Swagger 2 接口文档到 ApiFox 时接口重复的问题
🏷️ Swagger
项目中使用 Swagger 2 和 ApiFox 来管理文档。Swagger 依赖的版本是
- springfox-swagger2:2.9.2
- springfox-swagger-ui:2.9.2
但是更新了 ApiFox 的客户端版本( 2.2.19 )后发现:导入时相同路由的接口会自动覆盖。如果只导入一个服务,不会出现接口路由重复的情况。不过若项目中有多个服务,而且碰巧路由重复了,就会出现覆盖别的服务的接口文档的情况。之前的版本导入时可以设置为相同目录下且路由相同时才覆盖,但是新版没有这个设置项。另外数据模型的导入也有类似的问题。
根据 ApiFox 的更新日志,在 2.2.21-alpha.1 版中已经添加了 导入接口时,接口的匹配规则会根据每个目录的
接口唯一标识
进行匹配 的优化。等这个版本发布后,应该就不会再有本文中的问题了。
导入接口时有一个 接口唯一标志
的配置项,其中常用的是 Method & Path 和 OperationId 。大多数情况下都是使用 Method & Path 的方式,所以导致了上面的问题。
使用 OperationId 作为接口唯一标志倒是可以解决这个问题。在 Swagger 2 的 @ApiOperation
注解中设置 nickname 就可以了。
@ApiOperation(value = "用户登录", nickname = "user-service-login-post")
不过现有的接口都没有设置这个值,采用这种方式的话改动范围太大了,最后放弃了这种方案。
在导入时还有一个 接口路径加上 basePath 的开关,Swagger 的 /v2/api-docs
返回的响应中也有这个字段。默认为应用的 basePath (ApplicationBasePath),若未设置应用基础路径的话就是默认值 /
。
大多数微服务的方案中都不会修改默认的 basePath ,而是在网关中设置对应服务的路由。比如用户服务的接口在网关中一般会设置一个 /user/**
的路由。
下面是设置 basePath 的示例代码[1]:
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Value("${spring.application.name}")
private String applicationName;
@Autowired
private ServletContext servletContext;
@Bean
public Docket createRestApi() {
ApiInfo apiInfo = new ApiInfoBuilder()
.title("博客服务")
.description("服务描述...")
.version("1.0.0")
.build();
return new Docket(DocumentationType.SWAGGER_2)
.pathMapping("/")
.apiInfo(apiInfo)
.select()
.apis(RequestHandlerSelectors.basePackage("me.liujiajia.blog.user.controller"))
.paths(PathSelectors.any())
.build()
.pathProvider(new RelativePathProvider(servletContext) {
@Override
public String getApplicationBasePath() {
return "/" + applicationName + super.getApplicationBasePath();
}
});
}
}
其中的 pathProvider
方法就是指定 basePath 字段值的处理。示例中将 basePath 指定为当前服务的名称。
假设用户服务下有一个接口 /login
,应用名称为 user
,网关中也将路由设置为 /user/**
。则在当前服务中其路由为 /login
,通过 Swagger UI 页面和网关访问时路由则为 /user/login
。
在 ApiFox 中导入若开启了 接口路径加上 basePath 开关,导入的接口也会自动变成 /user/login
。这种方案可以保证从同一个网关中导入的各种服务 API 定义之间不会发生接口重复的情况。
这种方案好处是在 ApiFox 中对于同一个网关来说,每个环境只需要设置一个服务前置 URL(也就是网关的 URL 地址)就可以了。
坏处是若修改了网关路由配置,所有的接口文档都要重新导入。由于接口路径都变了,关联的测试用例也需要重新添加。
还有一个稍微不太方便的地方是本地开发环境的接口测试。不过这个可以采用添加配置项的方式解决:在本地启用时不修改 Swagger 的 basePath 。
总的来说不着急的话还是不建议修改 basePath ,等等 ApiFox 更新应该就没有这个问题了。