31

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

observer
  • 2,925
  • 1
  • 19
  • 38
CeeTee
  • 778
  • 1
  • 9
  • 17
  • The UNKNOWN_BASE_TYPE issue has been fixed with better inline schema handling in openapi-generator v6.0.0 release. Please give it a try and let us know if you're seeing the same issue via https://github.com/openapitools/openapi-generator/issues/new – William Cheng Jul 03 '22 at 09:48

4 Answers4

26

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

observer
  • 2,925
  • 1
  • 19
  • 38
  • I have been battling to generate a PHP client for an API that heavily uses anyOf and oneOf. After some googling and finding suprisingly few stack overflow questions arround this topic, I guess that support for polymorphism really is a strongly WIP topic for code generation? – FabianTe Oct 14 '21 at 13:26
  • 2
    Just ran into this issue too :( – Kehza Oct 26 '21 at 14:55
25

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.

Ivan Ponomarev
  • 442
  • 5
  • 11
Bludwarf
  • 824
  • 9
  • 21
  • 1
    When trying this solution, I am still getting: `@JsonSubTypes({ @JsonSubTypes.Type(value = ERRORUNKNOWN.class, name = "Obj1"), @JsonSubTypes.Type(value = ERRORUNKNOWN.class, name = "Obj2"), })` in the abstract model, which is failing compilation. – Tom Carmi Feb 10 '22 at 15:24
  • Hmm, it compiled but the compiled schema does not look correct, just says there is an object called 'discriminator' but nothing exist inside said object. Also this approach I don't think works if the property to switch on is an external one from the schema which it is in my situation and I can't control that – David S Sep 29 '22 at 10:41
  • 1
    This is the only solution that worked for me. Even when using the openapi-generator-maven-plugin v6.6.0, it didn't correctly interpret oneOf/anyOf – ihebiheb Jul 19 '23 at 18:46
5

We've added better oneOf and anyOf support to some generators such as java (okhttp-gson, jersey2, native), csharp-netcore, Go, PowerShell, R 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/

William Cheng
  • 10,137
  • 5
  • 54
  • 79
  • 9
    maven available 5.1.1 does not support oneof and anyof code generation. 5.2.0-SNAPSHOT and 6.0.0-SNAPSHOT are not available on maven . How are you suggesting to try these two version if they are supporting oneof? Have to use this utility in production code. – Harish Vashist Jun 21 '21 at 10:01
  • Please mention that the `csharp-netcore` generator also works for older frameworks too. We wasted a lot of time on this. – Dave Moten Mar 25 '22 at 04:52
  • v6.2.0 should have better for oneOf in the spring generator. Please give it a try. – William Cheng Oct 09 '22 at 07:54
  • @WilliamCheng v6.2.0 with Spring generates something like this: `List` for this `items: oneOf: - $ref:` – ACV Jan 03 '23 at 19:32
  • Actually that is an interface. It also generates the concrete class so that is fine.. – ACV Jan 03 '23 at 19:40
0

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"
    }
  }
}
Vít Zadina
  • 168
  • 8