Search code examples
javagradleswaggeropenapiswagger-codegen

How to use Swagger Codegen in Gradle for OpenAPI 3.0?


I have an OpenAPI 3.0 spec (in YAML format), and would like to generate Java code for the API. I want to do this as part of an automated build (preferably using Gradle), so I can create the service interface, and the implementation of the interface as part of an automated process.

This working example shows how to do it, however it uses a Swagger 2.0 specification YAML: https://github.com/galovics/swagger-codegen-gradle/tree/first-server-side

I've forked this example and added an OpenAPI 3.0 spec, however it then fails to build: https://github.com/robjwilkins/swagger-codegen-gradle/tree/openapi_v3_test

The error is:

failed to read resource listing com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'openapi': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false') at [Source: (String)"openapi: 3.0.0

(PR showing changes: https://github.com/robjwilkins/swagger-codegen-gradle/pull/1/files)

My understanding is the code which needs updated is in build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("io.swagger.codegen.v3:swagger-codegen:3.0.16")
    }
}

possibly io.swagger.codegen.v3:swagger-codegen:3.0.16 doesn't recognize OpenAPI 3.0?

The Swagger Core v3 project seems to be focused on generating a YAML/JSON spec from code (rather than code from spec): https://github.com/swagger-api/swagger-core

Any help with this problem would be appreciated. Thanks :)


Solution

  • I've now got this working (thanks to @Helen for help)

    The edits required were in build.grade.

    First I had to amend the build scripts to pull in a different dependency:

    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath('io.swagger.codegen.v3:swagger-codegen-maven-plugin:3.0.16')
        }
    }
    

    The change some of the imports:

    import io.swagger.codegen.v3.CodegenConfigLoader
    import io.swagger.codegen.v3.DefaultGenerator
    import io.swagger.codegen.v3.ClientOptInput
    import io.swagger.codegen.v3.ClientOpts
    import io.swagger.v3.parser.OpenAPIV3Parser
    

    And update the generateServer task:

    ext.apiPackage   = 'com.example.api'
    ext.modelPackage = 'com.example.model'
    
    task generateServer {
        doLast {
            def openAPI = new OpenAPIV3Parser().read(rootProject.swaggerFile.toString(), null, null)
            def clientOpts = new ClientOptInput().openAPI(openAPI)
            def codegenConfig = CodegenConfigLoader.forName('spring')
            codegenConfig.setOutputDir(project.buildDir.toString())
            clientOpts.setConfig(codegenConfig)
            def clientOps = new ClientOpts()
            clientOps.setProperties([
                    'dateLibrary'     : 'java8', // Date library to use
                    'useTags'         : 'true',  // Use tags for the naming
                    'interfaceOnly'   : 'true'   // Generating the Controller API interface and the models only
                    'apiPackage'       : project.apiPackage,
                    'modelPackage'     : project.modelPackage
            ])
            clientOpts.setOpts(clientOps)
    
            def generator = new DefaultGenerator().opts(clientOpts)
            generator.generate() // Executing the generation
        }
    }
    

    updated build.gradle is here: https://github.com/robjwilkins/swagger-codegen-gradle/blob/openapi_v3_test/user-service-contract/build.gradle