'How to use OpenAPI "oneOf" property with openapi-generator-maven-plugin when generating Spring code
I am developing an application with an Angular frontend and RESTful Spring Boot Backend
I found this very handy maven plugin openapi-generator-maven-plugin from org.openapitools. With its code generation capability, it helps enforce a "contract first" approach between the frontend and backend for our API. But our swagger file uses "oneOf" property in the requestBody and responseBody definitions. I've tried to generate Spring code from this, but the generated Java class has missing imports:
import com.pack.api.dto.OneOfLatteCoffeAmericanoCoffe;
import com.pack.api.dto.UNKNOWN_BASE_TYPE;
Is there away to cofigue the plugin to work with Swagger's oneOf property? I'm usig Spring Boot 2.3.1, Swagger 3.0 and Openapi-generator-maven-plugin 4.3
Solution 1:[1]
Currently, openapi-generator doesn't support oneOf
. This is a capability that had been newly introduced with OpenAPI v3 (FYI, only v2 and below are called "Swagger", it has then been renamed to OpenAPI). There are various generators (Java, Spring, lots of other languages). I have seen that contributions have been made during this year to enable oneOf
support.
To sum up, it looks like you have to wait a bit more until you can exploit this feature of the OpenAPI v3 spec using the generator for Spring.
Edit: It's also listed on the "short term roadmap":
OAS3.0 features support: anyOf, oneOf, callbacks, etc
Solution 2:[2]
If you can modify your swagger, you may replace the oneOf
with a reference to an abstract type.
For example, if your swagger looks like this :
components:
schemas:
'Parent':
'vehicle':
oneOf:
- type: object
properties:
'car_property':
type: string
- type: object
properties:
'truck_property':
type: string
You can modify it like that :
components:
schemas:
'Parent':
type: object
properties:
'vehicle':
$ref: '#/components/schemas/Vehicle'
#---------------------------------------------------------------------------
# Abstract class with discriminator 'vehicle_type'
#---------------------------------------------------------------------------
'Vehicle':
type: object
properties:
'vehicle_type':
type: string
enum: [ 'CAR', 'TRUCK' ]
discriminator:
propertyName: vehicle_type
mapping:
'CAR': '#/components/schemas/Car'
'TRUCK': '#/components/schemas/Truck'
#---------------------------------------------------------------------------
# Concrete classes
#---------------------------------------------------------------------------
'Car':
allOf:
- $ref: "#/components/schemas/Vehicle"
- type: object
properties:
'car_property':
type: string
'Truck':
allOf:
- $ref: "#/components/schemas/Vehicle"
- type: object
properties:
'truck_property':
type: string
This swagger modification makes the generator work. It handles the same JSON objects though I am not 100% sure it is semanticaly equivalent in OpenAPI specification.
Solution 3:[3]
We've added better oneOf and anyOf support to some generators such as java
(jersey2), csharp-netcore
and more. Please give it a try with the latest master. SNAPSHOT versions can be found in the project's README: https://github.com/OpenAPITools/openapi-generator/
Solution 4:[4]
For me csharp generated model object that is created is not correct. It generates following,
[DataMember(Name = "category", IsRequired = true, EmitDefaultValue = true)]
public OneOfobjectobjectobject Category { get; set; }
It creates an object starting with word Oneof and append three object since I have three oneOfs in my openapi spec doc for Category. Is there a way to return a dictionary or something? The above code doesn't compile. my openapi schema for category is as following
category:
title: Category
oneOf:
- title: Year
type: object
properties:
type:
title: Type
enum:
- year
type: string
additionalProperties: false
required:
- type
- title: Term
type: object
properties:
type:
title: Type
enum:
- term
type: string
parent:
title: Parent
oneOf:
- title: Academic Period
type: object
properties:
academicPeriod:
title: Academic Period
type: object
properties:
id:
title: ID
description: The global identifier for the Academic Period.
type: string
format: guid
pattern: ^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$
additionalProperties: false
required:
- id
additionalProperties: false
required:
- academicPeriod
- title: Academic Year
type: object
properties:
academicYear:
title: Academic Year
type: number
additionalProperties: false
required:
- academicYear
preceding:
title: Preceding
oneOf:
- type: object
properties:
id:
title: ID
description: The global identifier for the Preceding.
type: string
format: guid
pattern: ^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$
additionalProperties: false
required:
- id
- type: object
maxProperties: 0
additionalProperties: false
required:
- type
- title: Subterm
type: object
properties:
type:
title: Type
enum:
- subterm
type: string
parent:
title: Parent
type: object
properties:
id:
title: ID
description: The global identifier for the Parent.
type: string
format: guid
pattern: ^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$
additionalProperties: false
required:
- id
preceding:
title: Preceding
oneOf:
- type: object
properties:
id:
title: ID
description: The global identifier for the Preceding.
type: string
format: guid
pattern: ^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$
additionalProperties: false
required:
- id
- type: object
maxProperties: 0
sectionDateOverride:
title: Section Date Override
oneOf:
- type: string
enum:
- notAllowed
- type: string
maxLength: 0
additionalProperties: false
required:
- type
- parent
Solution 5:[5]
I using @openapitools/openapi-generator-cli and i tried this java snapshot https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.0.0-SNAPSHOT/openapi-generator-cli-${versionName}.jar and it worked for me.
Just need setup openapitools.json like this -
{
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
"spaces": 2,
"generator-cli": {
"version": "6.0.0-20211025.061654-22",
"repository": {
"downloadUrl": "https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.0.0-SNAPSHOT/openapi-generator-cli-${versionName}.jar"
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Ivan Ponomarev |
Solution 3 | William Cheng |
Solution 4 | |
Solution 5 | Vít Zadina |