Generate Java Spring API from OpenAPI 3

13,883

The problem seems to be in modelFilesConstrainedTo — it limits the classes to Error. Comment it out and it will work (classes will be generated).

However, there is another problem: outputDir. With your setting it will generate something like:

That's wrong. Also, as it is a generated source, it should not go to src/main. A better alternative is to generate it in build directory and then add it to the compilation classpath. Take a look at the demo project I've create for you, and here is the build.gradle.kts (it's almost like Groovy):

plugins {
    id("java-library")
    id("org.openapi.generator").version("4.0.1")
    id("org.springframework.boot").version("2.1.8.RELEASE")
}

repositories {
    jcenter()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web:2.1.8.RELEASE")
    api("io.springfox:springfox-swagger2:2.8.0")
    api("io.springfox:springfox-swagger-ui:2.8.0")
    api("org.openapitools:jackson-databind-nullable:0.1.0")
}

val spec = "$rootDir/docs/openapi/api.yml"
val generatedSourcesDir = "$buildDir/generated/openapi"

openApiGenerate {
    generatorName.set("spring")

    inputSpec.set(spec)
    outputDir.set(generatedSourcesDir)

    apiPackage.set("org.openapi.example.api")
    invokerPackage.set("org.openapi.example.invoker")
    modelPackage.set("org.openapi.example.model")

    configOptions.set(mapOf(
            "dateLibrary" to "java8"
    ))
}

sourceSets {
    getByName("main") {
        java {
            srcDir("$generatedSourcesDir/src/main/java")
        }
    }
}

tasks {
    val openApiGenerate by getting

    val compileJava by getting {
        dependsOn(openApiGenerate)
    }
}

Note that you'll also need a bunch of dependencies that are used in generated sources (annotations and Spring classes).

Share:
13,883

Related videos on Youtube

zolv
Author by

zolv

It started long time ago with Commodore C64...and it escalated quickly :) DIY enthusiast.

Updated on June 04, 2022

Comments

  • zolv
    zolv almost 2 years

    I tried to generate Spring REST interfaces from OpenAPI v3 YAML file. Build says:

    Successfully generated code to property(class java.lang.String, property(class java.lang.String, fixed(class java.lang.String, /home/zolv/workspaces/main/generation-test/src/main/java)))
    
    Deprecated Gradle features were used in this build, making it 
    incompatible with Gradle 6.0.
    Use '--warning-mode all' to show the individual deprecation warnings.
    See https://docs.gradle.org/5.5/userguide/command_line_interface.html#sec:command_line_warnings
    

    But there is no code generated in output directory.

    I followed OpenAPI generator gradle plugin doc doc.

    My build.gradle:

    plugins {
      id 'java-library'
      id "org.openapi.generator" version "4.1.1"
    }
    
    repositories {
      jcenter()
    }
    
    dependencies {
        implementation "org.openapitools:openapi-generator-gradle-plugin:3.3.4"
    }
    
    openApiGenerate {
      generatorName = "spring"
      inputSpec = "$rootDir/docs/openapi/api.yml".toString()
      outputDir = "$rootDir/src/main/java".toString()
      apiPackage = "org.openapi.example.api"
      invokerPackage = "org.openapi.example.invoker"
      modelPackage = "org.openapi.example.model"
      modelFilesConstrainedTo = [
              "Error"
      ]
      configOptions = [
          dateLibrary: "java8"
      ]
    }
    

    My api.yml:

    openapi: 3.0.2
    info:
      title: API Documentation
      version: 1.0.0
    servers:
      - url: http://localhost:8080/
    tags:
      - name: Users
    paths:
      /users:
        post:
          tags:
            - Users
          summary: Create user
          requestBody:
            content:
              application/json:
                schema:
                  $ref: '#/components/schemas/CreateUserRequest'
          responses:
            201:
              description: New user created
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/UserResponse'
    components:
      schemas:
        CreateUserRequest:
          title: CreateUserResponse
          required:
            - username
            - password
          type: object
          properties:
            username:
              type: string
              description: Users's username
              example: [email protected]
            password:
              type: string
              description: User's password
              example: $tR0nG_pA55vv0Rd
        UserResponse:
          title: UserResponse
          required:
            - id
            - username
          type: object
          properties:
            id:
              type: string
              description: Users's identifier
              example: "1"
            username:
              type: string
              description: Users's username
              example: [email protected]
    

    api.yml is properly gathered by generator (Build fails if there are any syntax errors in the file).

    It looks suspicious that build logs say: Successfully generated code to property(.... Doesn't mean the property contains the result of generation ?

    Gradle version:

    ------------------------------------------------------------
    Gradle 5.5
    ------------------------------------------------------------
    
    Build time:   2019-06-28 17:36:05 UTC
    Revision:     83820928f3ada1a3a1dbd9a6c0d47eb3f199378f
    
    Kotlin:       1.3.31
    Groovy:       2.5.4
    Ant:          Apache Ant(TM) version 1.9.14 compiled on March 12 2019
    JVM:          11.0.4 (Ubuntu 11.0.4+11-post-Ubuntu-1ubuntu218.04.3)
    OS:           Linux 4.15.0-1050-oem amd64
    

    Edit:

    I've checked example from gradle plugin, and code above works with Gradle v4, but not with 5. I'm still investigating.

  • zolv
    zolv over 4 years
    Thank You for Your very verbose answer! Generation output set as java/main was just for a test to be sure that I don't have a problem with missing directory. As it finaly started working, I noticed that it generates the whole project instead of just a Spring code (as I was expecting). I need to dig through documentation now, I hope there is some kind of switch to disable this. Thank You!
  • Shmarkus
    Shmarkus about 4 years
    For me, the modelFilesConstrainedTo removal did the trick, thanks