Can I have a polymorphic property that is not of type "Object"?
Hello.
I am trying to come up with a single openapi.yaml that would serve for both code generation and API documentation.
However, I'm having troubles with reaching both goals with a single file because of a polymorphism.
Every time I try I either get ugly "Example Values" in the online documentation or just blunt "Object" types in generated classes or both.
Let me illustrate: I have two endpoints, one of which returns a single polymorphic object and other returns a list of these.
That is "GET /allPets" - would yield a list of Pets and Dogs and "GET /randomPet" would return a single Pet.
If I would be writing my classes in a plain Java, then Pet would be an abstract class or an interface and Cat and Dog would inherit from/implement it. Therefore this abstract type would be used for both endpoints.
However, this is not something I achieve with OpenAPI. May be I am just approaching the problem from the wrong end.
Here is the definition:
openapi: "3.0.0" info: version: 1.0.0 title: PetStore paths: /randomPet: get: responses: '200': description: "a single random pet" content: application/json: schema: $ref: '#/components/schemas/SinglePetResponse' /allPets: get: responses: '200': description: "a single random pet" content: application/json: schema: $ref: '#/components/schemas/AllPetsResponse' components: schemas: SinglePetResponse: type: object properties: pet: oneOf: - $ref: "#/components/schemas/Dog" - $ref: "#/components/schemas/Cat" discriminator: propertyName: pet_type AllPetsResponse: type: array items: oneOf: - $ref: "#/components/schemas/Dog" - $ref: "#/components/schemas/Cat" discriminator: propertyName: pet_type Pet: type: object required: - pet_type properties: pet_type: type: string discriminator: propertyName: pet_type Dog: # "Dog" is a value for the pet_type property (the discriminator value) allOf: # Combines the main `Pet` schema with `Dog`-specific properties - $ref: '#/components/schemas/Pet' - type: object # all other properties specific to a `Dog` properties: bark: type: boolean breed: type: string enum: [Dingo, Husky, Retriever, Shepherd] Cat: # "Cat" is a value for the pet_type property (the discriminator value) allOf: # Combines the main `Pet` schema with `Cat`-specific properties - $ref: '#/components/schemas/Pet' - type: object # all other properties specific to a `Cat` properties: hunts: type: boolean age: type: integer
The classes I end up with essentially boil down to:
public class SinglePetResponse { private @Valid Object pet = null; }
and
public class AllPetsResponse extends ArrayList<Object> { }
On top of that the "SinglePetResponse" is rendered as an empty object in the UI.
It is important for me to nest these properties under other objects - because in the real system the responses are much more than just a list of objects - they have other fields, too.
What I would like to see is the "Pet" class used instead of "Object" and a better rendering in the UI (a random type or just a first time would suffice). A nice, but not required property would be the Pet class being abstract.
Is there a way to achieve this with OpenAPI 3?
Best regards,
Alexey Nezhdanov