Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate a property as schema definition in OpenApi 3.0

When using swagger 2.0, the java.util.Currency class got generated as a seperate definition. But when we generate OpenAPI 3.0, we run into the issue that swagger-core generates it as a property.


Generation of the OpenAPI 3.0 specification from the classes

We have f.e. this class:

import java.util.Currency; 

public class Wrapper {
   private Currency currency;
}

From this code we generate the openapi specification with the following plugin configuration:

      <plugin>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-maven-plugin</artifactId>
            <version>2.0.9</version>
            <configuration>
                <outputFileName>openapi</outputFileName>
                <outputFormat>YAML</outputFormat>
                <outputPath>....</outputPath>
                <resourcePackages>...</resourcePackages>
            </configuration>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>resolve</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

When generated this will result in this component definition:

components:
  schemas:
    Wrapper:
      type: "object"
      properties:
        currency:
          type: object
          properties:
            currencyCode:
              type: string
            defaultFractionDigits:
              type: integer
              format: int32
            numericCode:
              type: integer
              format: int32
            displayName:
              type: string
            symbol:
              type: string

Generation of the classes from the OpenAPI 3.0 specification

We then then generate the classes in another project with the following plugin:

The code to generate the classes form this openapi specification:

        <plugin>
            <groupId>org.openapitools</groupId>
            <artifactId>openapi-generator-maven-plugin</artifactId>
            <version>3.2.0</version>
            <executions>
                <execution>
                    <id>openapi-generation</id>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <inputSpec>${project.basedir}/src/main/resources/swagger.yaml</inputSpec>
                        <language>java</language>
                        <library>jersey2</library>
                        <generateSupportingFiles>false</generateSupportingFiles>
                        <configOptions>
                            <booleanGetterPrefix>is</booleanGetterPrefix>
                            <dateLibrary>threetenbp</dateLibrary>
                            <import-mappings>
                                Currency=java.util.Currency
                            </import-mappings>
                        </configOptions>
                        <generateApis>false</generateApis>
                        <generateApiDocumentation>false</generateApiDocumentation>
                        <generateModelTests>false</generateModelTests>
                        <generateModelDocumentation>false</generateModelDocumentation>
                    </configuration>
                </execution>
            </executions>
        </plugin>

This will result in a class named WrapperCurrency. The --import-mappings option does not seem to work since it's a property and not a schema. This would work if the Currency would be generated as a seperate Schema definition.


Desired result

Is there any way to either, annotate the property in such a way that the java.util.Currency will be generated as a schema? something along the lines of:

components:
  schemas:
    Wrapper:
      type: "object"
      properties:
        currency:
           $ref: "components/schemas/Currency"

    Currency:
      type: object
      properties:
        currencyCode:
          type: string
        defaultFractionDigits:
          type: integer
          format: int32
        numericCode:
            type: integer
            format: int32
        displayName:
          type: string
        symbol:
          type: string

Or is there a way to bind the --import-mappings option to a property instead of the object?

like image 655
Ivar Reukers Avatar asked Dec 09 '19 15:12

Ivar Reukers


1 Answers

Well, you may consider a workaround: adding an annotation @Schema(ref = "Currency") to the currency field will make the plugin skip generating properties. Unfortunately, it won't generate the schema definition for the Currency class either:

components:
  schemas:
    Wrapper:
      type: object
      properties:
        currency:
          $ref: '#/components/schemas/Currency'

I am not sure if it is an issue for you, as you are mapping it back to java.util.Currency anyways. But if it is, there is another hack: you can provide a static file with a partial schema (just the Currency definition) and configure the plugin to merge it with the generated schema (openapiFilePath parameter).

Plugin configuration:

      <plugin>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-maven-plugin</artifactId>
            <version>2.0.9</version>
            <configuration>
                ...
                <openapiFilePath>src/main/resources/currency.yaml</openapiFilePath>
                ...
            </configuration>
            ...
      </plugin>

currency.yaml:

components:
  schemas:
    Currency:
      type: object
      properties:
        currencyCode:
          type: string
        defaultFractionDigits:
          type: integer
          format: int32
        numericCode:
          type: integer
          format: int32
        displayName:
          type: string
        symbol:
          type: string

It's a hack, I know, but if there are no other options...

like image 149
Mafor Avatar answered Oct 29 '22 00:10

Mafor