11

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 :)

robjwilkins
  • 5,462
  • 5
  • 43
  • 59
  • Yes, Swagger Codegen 2.x is for OAS2 only. You need to use Codegen 3.x. If you change the classpath to `io.swagger.codegen.v3.swagger-codegen:3.0.16` does it work? – Helen Jan 23 '20 at 10:12
  • where do I get that dependency from? doesn't appear to be in mavenCentral? thanks! – robjwilkins Jan 23 '20 at 10:28
  • https://mvnrepository.com/artifact/io.swagger.codegen.v3/swagger-codegen/3.0.16. Previous comment should read `io.swagger.codegen.v3:swagger-codegen:3.0.16` (I made a typo). – Helen Jan 23 '20 at 10:32
  • got the library now thanks. Still get an error: 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') any ideas? – robjwilkins Jan 23 '20 at 11:03
  • Looks like the code or some other dependency expects an OAS2 file and cannot parse OAS3. Did you also update the [imports](https://github.com/robjwilkins/swagger-codegen-gradle/blob/openapi_v3_test/user-service-contract/build.gradle#L14-L15) from `io.swagger.codegen.NNN` to `io.swagger.codegen.v3.NNN`? – Helen Jan 23 '20 at 12:30
  • sorry, yes I've updated them and added another import (`io.swagger.codegen.v3:swagger-codegen-generators:1.0.16`) Build now errors: `> missing OpenAPI input!` Just trying to track down why! Updated build.gradle: https://github.com/robjwilkins/swagger-codegen-gradle/blob/openapi_v3_test/user-service-contract/build.gradle – robjwilkins Jan 23 '20 at 14:06

1 Answers1

9

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

robjwilkins
  • 5,462
  • 5
  • 43
  • 59
  • awesome, this helped me in moving further a lot, I am now facing issues with null pointer while creating a DefaultGenerator. I have used extra properties. – Bilbo Baggins Jan 29 '20 at 10:25
  • Okay, I saw the update, I am still getting NullPointer, not sure why, I have my code sam as yours. with gradle 4.9 – Bilbo Baggins Jan 30 '20 at 09:21
  • 1
    I figured it out, your code helped a lot :) thank you :) :) – Bilbo Baggins Jan 30 '20 at 10:17
  • This post helped to resolve my issue. Is there an option to disable generating API test ? "apiTests=false" did not work as mentioned in documentation https://github.com/swagger-api/swagger-codegen – Tilak Apr 01 '20 at 07:00
  • How would I set a templateDir or additionalProperties? – Maxim Therrien Jul 23 '22 at 02:00