cancel
Showing results for 
Search instead for 
Did you mean: 

Can I have a polymorphic property that is not of type "Object"?

New Member

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

 

 

1 REPLY 1
Staff

Re: Can I have a polymorphic property that is not of type "Object"?

hello @AlexeyNezhdanov 

 

I've just made some changes from java client generator and java server generator (spring, inflector, javajaxrs) related to this post.

 

Meantime next release is done you can try with this https://oss.sonatype.org/content/repositories/snapshots/io/swagger/codegen/v3/swagger-codegen-cli/3.... and let us know how it goes.

 

Best regards

New Here?
Join us and watch the welcome video: