Java - How do I get OpenAPI (Swagger) to recognise @BeanParam for path and query params?

Viewed 333

I'm dealing with Swagger doc generation for Java APIs that reuse a lot of common path structure across the board, so we've created a number of @BeanParam classes which hold @PathParams to help manage this.

We also have several @BeanParam classes which encapsulate multiple @QueryParams in one object, e.g. for a search request.

Here's an example of one API and a @BeanParam. This demonstration is a class holding @PathParams, but the problems are exactly the same with the @QueryParam-holding classes.

@POST
@Path("/entry/region/{regionId}/folder/{folderId}/entries")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
@Operation(operationId = "createEntry", description = "Create an entry")
@Tag(name = "external")
@RequestBody(content = @Content(mediaType = APPLICATION_JSON, schema = @Schema(ref = "EntryRequest")))
@APIResponse(responseCode = "201", ref = "Created")
@APIResponse(responseCode = "400", ref = "BadRequest")
public Response createEntry(@BeanParam EntryPath path,
                            @NotNull @Valid EntryRequest request) {
    return entryCreateService.createEntry(path, request);
}

And here's the class used as the @BeanParam:

public class EntryPath {

    @Parameter(in = ParameterIn.PATH)
    @PathParam("regionId")
    protected String regionId;
    
    @Parameter(in = ParameterIn.PATH)
    @PathParam("folderId")
    protected String folderId;

    public String getRegionId() {
        return regionId;
    }

    public String getFolderId() {
        return folderId;
    }
}

This is an example; we've got various other @BeanParams going up to three or four path parameters (and some including @QueryParams on top of these).

Now when generating an OpenAPI / Swagger file using the code generator, the @BeanParam isn't picked up on at all. I expect to find the path parameters it encapsulates included. Instead, what we see is this:

paths:
  /entry/region/{regionId}/folder/{folderId}/entries:
    post:
      tags:
      - external
      description: Create an entry
      operationId: createEntry
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EntryRequest'
      responses:
        "201":
          $ref: '#/components/responses/Created'
        "400":
          $ref: '#/components/responses/BadRequest'
...

The path params inside the 'EntryPath' BeanParam should be included here, but they've been passed over completely. Whereas, when we do use a simple @PathParam in the method signature (in other APIs), there's no issue.

I've tried several things to fix this, like

  • annotating the BeanParam classes with @Schema on the class and its fields (as we do for request body classes),
  • adding more fields to the @PathParam annotations inside the BeanParam class: e.g. @Parameter(in = ParameterIn.PATH, name = "regionId", required = true)
  • sticking @ApiModel and/or @ApiModelProperty on the BeanParam in the method signature and the BeanParam itself,
  • adding swagger-jersey2-jaxrs as a dependency as suggested elsewhere online,
  • combinations of these

No success.

Really hoping someone can offer help on this - it's been a bit of a dead end so far.

0 Answers
Related