user966217
user966217

Reputation: 35

org.openapi.generator to Java client + model with oneOff in swagger

I'm currently enrolled with a spring-boot project, and they are using an API first approach which I think is great… except that this approach leads to us generating our ingoing API clients + input models, and the chosen tool org.openapi.generator 5.3.0 is really bad at it.

I have an API spec like this (I removed non-important details):

/dummypath/{id}/documentation-demand':
 get:
  tags:
    - dummy-documentation-demand
  parameters:
    -
      name: id
      schema:
        $ref: '#/components/schemas/someId'
      in: path
      required: true
  responses:
    '200':
      content:
        application/json:
          schema:
            type: array
            items:
              allOf:
                - $ref: '#/components/schemas/DocumentationDemand'
      description: 'Success.
    

DocumentationDemand:
  oneOf:
    - $ref: '#/components/schemas/DocumentationDemandOne'
    - $ref: '#/components/schemas/DocumentationDemandTwo'
  discriminator:
    mapping:
      ONE: '#/components/schemas/DocumentationDemandOne'
      TWO: '#/components/schemas/DocumentationDemandTwo'
    propertyName: type
  required:
    - type
  properties:
    type:
      type: string
      enum:
        - ONE
        - TWO

DocumentationDemandOne:
  type: object
  properties:
    type:
      type: string
      enum:
        - ONE
DocumentationDemandTwo:
  type: object
  properties:
    type:
      type: string
      enum:
        - TWO

Basically I want an endpoint that gives a list of objects, that differ. But the "type" attribute tells you which one it is. In java this "type" doesn't make much sense, since the instance knows what it is, but for JSON it makes sense.

The generated models from the plugin seem all wrong. There is no common type for the two concrete classes, neither through interface or superclass. Secondly the discriminator map seems to wholly ignored. There is no common type enum created, no hardcoded type on the concrete classes. Is org.openapi.generator lacking support for this scenario, and if so, are there better generator plugins out there? Or is the an alternative way to express this in swagger? I've tried using v.5.4.0 but it is no better.

EDIT:

So I've tried changing my spec to this:

/dummypath/{id}/documentation-demand':
 get:
   tags:
     - dummy-documentation-demand
   parameters:
     -
      name: id
      schema:
        $ref: '#/components/schemas/someId'
      in: path
      required: true
  responses:
    '200':
      content:
        application/json:
          schema:
            type: array
            items:
              allOf:
                - $ref: '#/components/schemas/DocumentationDemand'
      description: 'Success.
    

DocumentationDemand:
  discriminator:
    mapping:
      DocumentationDemandOne: '#/components/schemas/DocumentationDemandOne'
      DocumentationDemandTwo: '#/components/schemas/DocumentationDemandTwo'
    propertyName: type
  required:
    - type
  properties:
    type:
      type: string

DocumentationDemandOne:
  type: object
  
DocumentationDemandTwo:
  type: object
  

And when the above model is returned as JSON the "type" property is not set...I mean I can always add "type" as an attribute on the two subtypes and set it manually, but come on...is there no functionallity (or support in plugin?) from discriminator ?

Upvotes: 0

Views: 2963

Answers (1)

Rob Spoor
Rob Spoor

Reputation: 9100

The OpenAPI generator doesn't support all of the OAS3.0 features yet. It's listed on their roadmap: https://openapi-generator.tech/docs/roadmap/

OAS3.0 features support: anyOf, oneOf, callbacks, etc

There are still several open issues for this: https://github.com/OpenAPITools/openapi-generator/issues?q=is%3Aissue+is%3Aopen+oneof

Unfortunately that means you'll have to wait until support is added, or help implement support through a pull request, or find a different generator.

When we encountered this issue, we solved it in two ways that probably won't help you:

  1. We updated the API spec where we could to not use oneOf at all (allOf worked OK).

  2. For a spec we couldn't update, we manually created the model classes using Jackson's polymorphism mechanisms (based on model classes generated earlier).

Upvotes: 1

Related Questions