Using inheritance and having both base type and subtypes in endpoints breaks the object hierarchy
Hi all, I'm using swagger 2.1.0 to annotate my JAX-RS ressources and to generate the openAPI documentation. I'm facing a problem with inheritance. In order to expose the situation we can take the Pet example from the openAPI specification. I implemented it as follows in java with jackson annotations:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ @Type(value = Cat.class), @Type(value = Dog.class) }) public class Pet { private String name; public final String getName() { return name; } public final void setName(String name) { this.name = name; } }
public class Cat extends Pet { public enum HuntingSkill { clueless, lazy, adventurous, aggressive}; private HuntingSkill huntingSkill; public final HuntingSkill getHuntingSkill() { return huntingSkill; } public final void setHuntingSkill(HuntingSkill huntingSkill) { this.huntingSkill = huntingSkill; } }
public class Dog extends Pet { private int packSize; public final int getPackSize() { return packSize; } public final void setPackSize(int packSize) { this.packSize = packSize; } }
and I define the following two Endpoints in a JAX-RS resource:
@Path("/") public final class SwaggerTestRS { @GET @Produces(MediaType.APPLICATION_JSON) @Path("/pet/{name}") @Operation( summary = "Gets the pet having the given name", responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Pet.class))) ) public Response getPet( @PathParam("name") String name) { return Response.ok().build(); } @GET @Produces(MediaType.APPLICATION_JSON) @Path("/pet/cat/{name}") @Operation( summary = "Gets the cat having the given name", responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Cat.class))) ) public Response getCat( @PathParam("name") String name) { return Response.ok().build(); } }
The endpoint getPet() is defined to return a Pet and getCat() a Cat. Out of this api the following openAPI documentation gets generated:
openapi: 3.0.1 paths: /pet/{name}: get: summary: Gets the pet having the given name operationId: getPet parameters: - name: name in: path required: true schema: type: string responses: "200": content: application/json: schema: $ref: '#/components/schemas/Pet' /pet/cat/{name}: get: summary: Gets the cat having the given name operationId: getCat parameters: - name: name in: path required: true schema: type: string responses: "200": content: application/json: schema: $ref: '#/components/schemas/Cat' components: schemas: Cat: type: object properties: name: type: string huntingSkill: type: string enum: - clueless - lazy - adventurous - aggressive Dog: type: object allOf: - $ref: '#/components/schemas/Pet' - type: object properties: packSize: type: integer format: int32 Pet: required: - type type: object properties: name: type: string type: type: string discriminator: propertyName:
Dog does inherit from Pet with the "allOf" definition, cat on the other hand does not. So Cat is no more a Pet and is no more an acceptable return type for the getPet() endpoint.
By removing the getCat() endpoint, the openApi documentation is generated as I would expect, with both Dog and Cat "extending" Pet.
Is this the expected behaviour or might it be a bug?
Thank you very much for your thoughs and maybe workarounds!