0

我正在开发一个休息应用程序。

某些端点需要自定义标头参数,与授权无关。我使用 jax-rs NameBinding 创建了一个自定义注释。这是一个使用示例:

@GET
@RequiresBankHeader
public int get(
        @HeaderParam("bank")
        @Parameter(ref = "#/components/parameters/banks")
                String bank) {        
    return someService.getSomeInformation();
}

有一个提供程序拦截此调用并使用标头参数中的信息执行一些例程。

问题是我必须在任何地方重复 '@HeaderParam("bank") @Parameter(ref = "#/components/parameters/banks") String bank',这样它才会出现在 Swagger 中,即使服务类没有需要它。我至少能够使用 ref = "#/components/parameters/banks" 重用参数定义,并在 OpenAPI.yml 文件中声明它,Quarkus 可以很好地与生成的代码合并。

但我也想创建和拦截器,以便在存在 RequiresBankHeader 注释时动态添加 OpenApi 定义。

有没有办法做到这一点?

4

2 回答 2

0

正如 Roberto Cortez 所提到的,MP OpenAPI 规范提供了一种将元数据贡献给 openapi.yml 文件的编程方式。

在 JAX-RS 端点定义中检测到注释是不可能的,但它足以自动化我需要的东西。由于所有具有 RequiresBankHeader 的方法都返回相同的模式,因此我能够像这样破解它:

public class OpenApiConfigurator implements OASFilter {

@Override
public Operation filterOperation(Operation operation) {
    operation.getResponses().getAPIResponses().values().stream().
            map(APIResponse::getContent).
            filter(Objects::nonNull).
            map(Content::getMediaTypes).
            flatMap(mediaTypes -> mediaTypes.values().stream()).
            map(MediaType::getSchema).
            filter(Objects::nonNull).
            map(Schema::getRef).
            filter(Objects::nonNull).
            filter(ref -> ref.contains("the common response schema")).
            findAny().
            ifPresent(schema -> {
                ParameterImpl parameter = new ParameterImpl();
                parameter.setRef("#/components/parameters/banks");
                operation.addParameter(parameter);
            });
    return operation;
}

应使用 mp.openapi.filter=com.yourcompany.OpenApiConfigurator 在应用程序属性中配置 OpenApiConfigurator

于 2021-02-12T11:33:31.303 回答
0

我认为您不能使用拦截器来修改生成的 Openapi 模式输出。如果给定端点上的所有方法都需要一些参数,您可以在类级别指定它,如下所示:

@Path("/someendpoint")
public class MyEndpoint {
  
    @HeaderParam("bank")
    @Parameter(name = "bank")
    String bank;

    @GET
    public Response getAll() {return Response.ok().build()}

    @GET
    @Path("{id}")
    public Response someMethod(@PathParam("id") String id) {return Response.ok().build();}
}
于 2021-01-29T15:57:38.387 回答