Skip to content

Swagger Codegen migration (swagger codegen generators repository)

K. Alex Mills edited this page Apr 30, 2018 · 17 revisions

Overview

Swagger v3 (also known as OpenAPI 3) is really different from the v2. For the specification have a look at: A Visual Guide to What's New in Swagger 3.0

This means that a lot of the generators needs to be rewritten.

In addition, some other technical and infrastructure changes were made. Some important points:

This means that there is some migration work is required in order to be able to generate code using OpenAPI version 3 as input.

This pages contains information in order to help potential contributors.

Steps

Codegen classes

Create (or copy and paste) the Codegen classes from swagger-codegen from 3.0.0 branch to swagger-codegen-generators master branch. The new classes go in a subfolder of src/main/java.

The classes already read the OpenAPI 3 Specification and work with the corresponding classes (the swagger 2.0 classes have been already replaced)

New packages

In the swagger-codegen-generator project, a new structure was proposed. Instead of having everything in the io.swagger.codegen.languages package, package per languages should be created.

packages

Example:

  • Common classes: io.swagger.codegen.languages
  • Classes for Java code generation: io.swagger.codegen.languages.java
  • Classes for PHP code generation: io.swagger.codegen.languages.php
Top level class

The new top level class is DefaultCodegenConfig (from the swagger-codegen-generators module) instead of DefaultCodegen (from the swagger-codegen)

Naming convention

Some classes have the suffix: Generator. In order to keep consistency all migrated generators use Codegen as suffix.

Example: StaticHtmlGenerator => StaticHtmlCodegen

Template Version handling

A new member templateVersion was added in DefaultCodegenConfig. Of course there is also a getter: getTemplateVersion()

The processOpts() method needs to reads the value and to set the appropriate templateDir value accordinally. Example:

     @Override
     public void processOpts() {
         super.processOpts();
 
         String templateVersion = getTemplateVersion();
         if (StringUtils.isNotBlank(templateVersion)) {
             embeddedTemplateDir = templateDir = String.format("%s" + File.separator + "JavaInflector", templateVersion);
         } else {
             embeddedTemplateDir = templateDir = String.format("%s" + File.separator + "JavaInflector", DEFAULT_TEMPLATE_VERSION);
         }

TODO: this snippet might change with swagger-codegen/#7721, follow discussion there.

TemplateFiles maps manipulation

In AbstractJavaCodegen, following block was moved from the constructor to processOpts():

modelTemplateFiles.put("model.mustache", ".java");
apiTemplateFiles.put("api.mustache", ".java");
apiTestTemplateFiles.put("api_test.mustache", ".java");
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");

Some sub-class of AbstractJavaCodegen perform additional modifications on those maps. The corresponding code should also be moved from the constructor to the processOpts() options

Package Name handling

In the super class DefaultCodegenConfig the package hanlding was changed in processOpts() to ensure that the values can be set with the setter (example: config.setModelPackage("xyz.company.example.model")) or with the additionalProperties map (example: config.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "xyz.company.example.model")). => See #55.

If your generator also manipulate the package names (modelPackage, apiPackage ...) you might need to move your custom logic for the super call (from <2> to <1>):

@Override
public void processOpts() {

    // <1> custom handling, that needs to be made before the default handling.

    super.processOpts();

    // <2> other handling.
}

See commit 3e96e04 for an example.

Remove guava elements

In the new project, we do not like to depend from guava anymore. See swagger-codegen-generators/#5.

  • ImmutableMap => Collections.singletonMap(.., ..) or Collections.unmodifiableMap(..)
  • ImmutableList => Collections.singletonList(.., ..) or Collections.unmodifiableList(..)
  • com.google.common.base.Function => java.util.Function & lambda

...

Remove fields declaration hiding another field or variable

Having field declarations that hides another field or variable is in my opinion a bad practice in java. Name shadowing can cause subtle errors and should be avoided.

See: Pull Request #40

You can configure your IDE to detect those problems for you.

Replace system properties with custom arguments

Reference issue swagger-codegen-generators/#27 See commit dac94a7 for an example.

TODO: improve description

Mustache Templates

Create code generator templates. Keep in mind that these templates now work with handlebars. The templates go in a subfolder of src/main/resources (in the v2 subfolder).

The existing templates (for Swagger v2) can be used as reference: in the swagger-codegen repository in the master branch (path: /modules/swagger-codegen/src/main/resources/)

The templates must be migrated: See the 'Swagger Codegen migration from Mustache and Handlebars templates.' page in the wiki.

Register the generators

Add your new class (full qualified name) in the service registry of the swagger-codegen-generator project (master branch). Path: /src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig

Cleanup work in the swagger-codegen repository

Add a @Deprecated mention on the old classes, and precise in the Javadoc where the new class is located.

/**
 * new version of this class can be found on: https://github.com/swagger-api/swagger-codegen-generators
 * @deprecated use <code>io.swagger.codegen.languages.java.JavaClientCodegen</code> instead.
 */
@Deprecated
public class JavaClientCodegen extends ...

Have a look at the tests scripts:

Find the one testing your generator (you can search for “-l xxx” where xxx is the name of your language)

The java command there needs to be uncommented in order to activate the test back. The arguments might need to be updated.

Work in progress

Done: