英文:
OpenApi 3.0 Register Filter to exclude methods with specific Tags
问题
我们有一个需求,需要使用Java注解生成API的多个定义。我们对任何建议都持开放态度,但提出的建议似乎是一个可行的选择,如果我们能够弄清楚如何使其工作。
基本上,我们需要从单个代码库生成两个API文档。第一个应该包括所有已扫描的资源。这个没有问题,我们可以很好地实现这一点。
以下是一个示例注解方法的摘要版本:
@POST
@Path("/some/path")
@Consumes("application/json")
@Operation(
summary = "Do something...",
description = "Do something..."
)
@Tags({@Tag(name = "example-tag")})
@RequestBody(
description = "Do something...",
required = true,
content = @Content(
schema = @Schema(
implementation = Example.class
)
)
)
@ApiResponses({
@ApiResponse(
responseCode = "201",
description = "Do something...",
content = @Content(
schema = @Schema(
implementation = Example.class
)
)
)
})
public ApiResponse doSomething() throws Exception {
...
}
以下是我们如何构建文档的方式:
OpenAPI oas = new OpenAPI();
// 基本文档
Info info = new Info()
.title("...")
.description("...")
.termsOfService("...")
.contact(new Contact().email("..."))
.version("...");
// API服务器
Server server = new Server().url("...");
// 认证方案
SecurityScheme scheme = new SecurityScheme()
.name("...")
.type(...)
.scheme("...")
.in(...);
Components components = new Components().addSecuritySchemes("example-auth", scheme)
oas.info(info);
oas.addServersItem(server);
oas.components(components);
ModelConverters instance = ModelConverters.getInstance();
instance.addConverter(new MultimapConverter());
SwaggerConfiguration oasConfig = new SwaggerConfiguration()
.openAPI(oas)
.prettyPrint(true)
.resourcePackages(Stream.of("...").collect(Collectors.toSet()));
OpenAPI openApi = new JaxrsOpenApiContextBuilder()
.openApiConfiguration(oasConfig)
.buildContext(true)
.read();
目前为止一切顺利。我们最终得到了包含所有内容的定义。现在我们需要创建第二个定义。这一次,它需要排除所有包含@Tag=(name = "private")
的操作。
我创建了一个扩展了AbstractSpecFilter的过滤器,名为TagFilter
。我已经重写了实现,并将其添加到了SwaggerConfiguration
的过滤器类中:
SwaggerConfiguration oasConfig = new SwaggerConfiguration()
.openAPI(oas)
.filterClass(TagFilter.class.getName()) // 也尝试了getCanonicalName()
.prettyPrint(true)
.resourcePackages(Stream.of("...").collect(Collectors.toSet()));
不幸的是,过滤器类从未被实例化。不确定如何以其他方式拦截操作以将它们移除。我们脑海中还出现了其他选项,比如使用@Hidden
注解,如果我们找到一种方法可以强制其中一个定义忽略@Hidden
。
英文:
We have a requirement to generate multiple definitions of an API using the Java annotations. We are open to any and all suggestions but the one proposed seemed like a viable option if we could work out how to get it to work.
We basically need to generate 2 API docs from a single code base. The first should include ALL the scanned resources. This one is no problem and we can achieve this fine.
Here is the abridged version of an example annotated method:
@POST
@Path("/some/path")
@Consumes("application/json")
@Operation(
summary = "Do something...",
description = "Do something..."
)
@Tags({@Tag(name = "example-tag")})
@RequestBody(
description = "Do something...",
required = true,
content = @Content(
schema = @Schema(
implementation = Example.class
)
)
)
@ApiResponses({
@ApiResponse(
responseCode = "201",
description = "Do something...",
content = @Content(
schema = @Schema(
implementation = Example.class
)
)
)
})
public ApiResponse doSomething() throws Exception {
...
}
And here is how we build the docs:
OpenAPI oas = new OpenAPI();
// The basic docs
Info info = new Info()
.title("...")
.description("...")
.termsOfService("...")
.contact(new Contact().email("..."))
.version("...");
// The API server
Server server = new Server().url("...");
// The authentication schemas
SecurityScheme scheme = new SecurityScheme()
.name("...")
.type(...)
.scheme("...")
.in(...);
Components components = new Components().addSecuritySchemes("example-auth", scheme)
oas.info(info);
oas.addServersItem(server);
oas.components(components);
ModelConverters instance = ModelConverters.getInstance();
instance.addConverter(new MultimapConverter());
SwaggerConfiguration oasConfig = new SwaggerConfiguration()
.openAPI(oas)
.prettyPrint(true)
.resourcePackages(Stream.of("...").collect(Collectors.toSet()));
OpenAPI openApi = new JaxrsOpenApiContextBuilder()
.openApiConfiguration(oasConfig)
.buildContext(true)
.read();
Ok so far so good. We end up with a definition that contains everything. Now we need to create a second definition. This time it needs to exclude all operations that contain the @Tag=(name = "private")
.
I created a filter that extended AbstractSpecFilter called TagFilter
. I have overridden the implementation and then added it to the filter class of the SwaggerConfiguration
:
SwaggerConfiguration oasConfig = new SwaggerConfiguration()
.openAPI(oas)
.filterClass(TagFilter.class.getName()) // Also tried getCanonicalName()
.prettyPrint(true)
.resourcePackages(Stream.of("...").collect(Collectors.toSet()));
Unfortunately the filter class is never instantiated. Not sure how else to intercept the operations to remove them. Other options that have crossed our mind is to use the @Hidden
annotation if we could find a way to force one of the definitions to ignore the @Hidden
.
专注分享java语言的经验与见解,让所有开发者获益!
评论