How to access vendor extensions in api.mustache regarding imports when endpoints are regrouped by tags

1.4k Views Asked by At

Problem

The issue concerns swagger codegen and using multiple files to define specs. I have two REST APIs with two different files specs1.yml and specs2.yml.

These specs have some models/schemas/definitions (I use swagger 2.0) in common.

I'd like to factorize these definitions in a core.yml file. I can then reference these in specs1 and specs2.

The issue is that swagger codegen generates these models as part of specs1 and specs2. What I'd like is processing the core.yml file, generating classes in a core package, and then having the specs1/2 generated classes referencing the classes in the core package when it's a common one.


Technical Stack

Maven / Java / JAXRS-CXF REST API

Maven 3.6.0

Java 1.8.0_201

swagger-jaxrs 1.5.16

CXF 3.1.14

swagger-codegen-maven-plugin 2.4.7


Code Example

Swagger Specs YML

I have a tag named e.g. "Super Tag" in my swagger specs definition. Multiple endpoints are regrouped under that tag. For the sake of a minimal PoC of my issue, let's go with one endpoint: specs1.yml

swagger: "2.0"

tags:
  - name: "Super Tag"
    x-core-imports: [ErrorResponse] # Trying this at tag level
    x-imports: [ABody]              # Trying this at tag level

paths:

  /someEndpointPath:
    post:
      x-core-imports: [ErrorResponse] # --> import bla.core.api.models.ErrorResponse
      x-imports: [ABody]              # --> import bla.project.api.models.ABody
      tags:
        - "Super Tag"
      operationId: postToSomeEndpoint
      consumes:
        - application/json
      produces:
        - application/json
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/ABody' # This model is defined in this file
      responses:
        204:
          description: "Successful response"
        400:
          description: "Bad request error"
          schema:
            $ref: '../CORE.yml#/definitions/_ErrorResponse'
            # I'm importing this model definition from another file

definitions:
  ABody:
    type: object
    field:
      type: string

Swagger Codegen Debugging

I tried seeing where the vendor extensions would be added with regards to imports: [{ "import": ... }] (which is what's read from the api.mustache template, see below)

> java -DdebugSupportingFiles -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -i specs.yml -l java > result.json

I can see result.json

"apiInfo" : {
      "apis" : { [
            "parent" : [ ],
            "generatorClass" : "io.swagger.codegen.languages.JavaClientCodegen",
            "supportJava6" : false,
            "sortParamsByRequiredFlag" : true,
            "groupId" : "io.swagger",
            "invokerPackage" : "io.swagger.client",
            "classVarName" : "superTag",
            "developerEmail" : "[email protected]",
            "generateModelDocs" : true,
            "hasImport" : true,
            "generateModelTests" : true,
            "generateApiTests" : true,
            "classFilename" : "SuperTagApi",
            "usePlayWS" : false,
            "generateModels" : true,
            "serializableModel" : false,
            "playVersion" : "play25",
            "inputSpec" : "specs.yml",
            "artifactUrl" : "https://github.com/swagger-api/swagger-codegen",
            "developerOrganization" : "Swagger",
            "baseName" : "SuperTag",
            "package" : "io.swagger.client.api",
            "imports" : [ {
                  "import" : "io.swagger.client.model.ABody"
            }, {
                  "import" : "io.swagger.client.model.ErrorResponse"
            } ]
            ...
      ] }
}

Swagger Templates

We can see in the api.mustache template

package {{package}};

{{#imports}}import {{import}};
{{/imports}}

I'm using the maven swagger codegen plugin with the following options:

<modelPackage>com.mysite.myproject.api.models</modelPackage>
<apiPackage>com.mysite.myproject.api</apiPackage>

So in my generated java class I will get:

SuperTagApi.class

package com.mysite.myproject.api;


import com.mysite.myproject.api.models.ErrorResponse;
import com.mysite.myproject.api.models.ABody;

What I'd like to do is have a means to tell swaggercodegen that I want one class imported as it is now, but the second imported from another package.

To do that, my idea was using vendor extensions (as you can see above) and manually list the classes that I want imported from a given package (that will actually be generated from the CORE.yml file) and the ones that are defined in my specs.yml where I want the original generated package name.

I tried adding x-core-imports vendor-extension to multiple different places trying to get access to them. None put them at the same level as the imports: [{ "import": ... }] section of the result.json... This is because different endpoints/methods are regrouped under the same file when their tag is identical.

I modified my api.mustache like so:

{{^vendorExtensions.x-imports}}
{{#imports}}import {{import}};
{{/imports}}
{{/vendorExtensions.x-imports}}

{{#vendorExtensions.x-imports}}
{{#vendorExtensions.x-core-imports}}
import com.mysite.core.api.models.{{.}};
{{/vendorExtensions.x-core-imports}}
import com.mysite.myproject.api.models.{{.}};
{{/vendorExtensions.x-imports}}

Do you know at which level in the yml file I have to put my vendor extensions to be able to access them from api.mustache? (Without modifying swagger codegen, just modifying templates and yml specs files)

0

There are 0 best solutions below