0

I am developing a rest application.

Some endpoints require a custom header parameter, not related to authorisation. I created a custom annotation using jax-rs NameBinding. Here is an usage example:

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

There is a provider that intercepts this call and do some routine using the information in the header parameter.

The problem is that I have to repeat '@HeaderParam("bank") @Parameter(ref = "#/components/parameters/banks") String bank' everywhere, just so it appears in Swagger, even though the service classes do not need it. I was able to at least reuse the parameter definition with ref = "#/components/parameters/banks", and declaring it in the OpenAPI.yml file, that Quarkus merges with generated code very nicely.

But I also want to create and interceptor to dynamically add this do the OpenApi definition whenever RequiresBankHeader annotation is present.

Is there a way to do it?

AmsterdamLuis
  • 341
  • 3
  • 21
  • The MP OpenAPI spec provides a programmatic way to contribute metadata to the `openapi.yml` file. Not sure if it is possible to do it the way you want, but I'll probably start there: https://github.com/eclipse/microprofile-open-api/blob/master/spec/src/main/asciidoc/microprofile-openapi-spec.adoc#programming-model – Roberto Cortez Jan 28 '21 at 23:51
  • @RobertoCortez Thanks. That link guided me to the solution. – AmsterdamLuis Feb 12 '21 at 11:26

2 Answers2

0

I dont think you can use interceptors to modify the generated Openapi schema output. If all methods on a given endpoint require some parameter, you can specify it on class level like so:

@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();}
}
yntelectual
  • 3,028
  • 18
  • 24
0

As mentioned by Roberto Cortez, the MP OpenAPI spec provides a programmatic way to contribute metadata to the openapi.yml file.

It is not possible to detect an annotation in the JAX-RS endpoint definition, but it was good enough to automate what I needed. Since all methods that had the RequiresBankHeader return the same Schema, I was able to hack it like this:

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;
}

OpenApiConfigurator should be configure in the application properties, using mp.openapi.filter=com.yourcompany.OpenApiConfigurator

AmsterdamLuis
  • 341
  • 3
  • 21