Reputation: 35
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
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:
We updated the API spec where we could to not use oneOf
at all (allOf
worked OK).
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