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!