swagger-api / swagger-api/swagger-codegen

Import mappings not generated when used as request body

Open
#12,121 1 comment 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

I'm using swagger codegen through the maven plugin swagger-codegen-maven-plugin v3.0.41, to generate jaxrs-spec server stubs and typescript-angular client implementation. Part of the API is not described by Swagger by imported with "import mappings". Those external types are used both as request and response bodies.

With version 1.5.22, everthing was fine.

After upgrading to v3.0.41, request bodies using an imported type are no longer generated. All the "put" and "post" methods are missing their main argument. This applies to both the Java and Typescript generated codes.

Please note response bodies refering to imported mapping are properly generated: return type is correct and is properly imported.
Other cases look OK: for instance a request body refering to a Swagger-defined type, which is itself is refering to an imported mapping, does work.

This problem does not look related to this issue, because it is not Java-specific (edit: I may have encountered two problems at the same time, with also this bug for typescript, so it may be Java specific I can't tell) and adding https://github.com/swagger-api/swagger-codegen/issues/10419 did not help.

Here is an extract from my Swagger file:

paths:
  /products/{productName}/versions/{versionName}/envs:
    put:
      tags:
        - postit
      summary: Save environment
      operationId: putEnvironment
      parameters:
        - name: productName
          in: path
          required: true
          schema:
            type: string
        - name: versionName
          in: path
          required: true
          schema:
            type: string
        - name: If-None-Match
          in: header
          schema:
            type: string
            enum:
              - '*'
      requestBody:
        content:
          application/json:
            schema:
              $ref: "Environment"  # Imported Mapping
      responses:
        200:
          description: OK
          content: {}
        412:
          description: Environment already exists
          content: {}

Corresponding generated code is missing the request body:

    @PUT
    @Path("/{productName}/versions/{versionName}/envs")
    @Consumes({ "application/json" })
    @Operation(summary = "Save environment", description = "", tags={ "postit" })
    @ApiResponses(value = { 
        @ApiResponse(responseCode = "200", description = "OK"),
        @ApiResponse(responseCode = "412", description = "Environment already exists")
    })
    public Response putEnvironment( @PathParam("productName")

Same in Typescript:

    public putEnvironment(productName: string, versionName: string, ifNoneMatch?: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
    public putEnvironment(productName: string, versionName: string, ifNoneMatch?: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
    public putEnvironment(productName: string, versionName: string, ifNoneMatch?: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
    public putEnvironment(productName: string, versionName: string, ifNoneMatch?: string, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
...

Here is the corresponding pom.xml :

<plugin>
    <groupId>io.swagger.codegen.v3</groupId>
    <artifactId>swagger-codegen-maven-plugin</artifactId>
    <version>3.0.41</version>
    <executions>
        <execution>
            <id>generate-java-server</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/api3.yml</inputSpec>
                <apiPackage>com.bouygtel.postit.service</apiPackage>
                <modelPackage>com.bouygtel.postit.service.model</modelPackage>
                <generateApiTests>false</generateApiTests>
                <generateApiDocumentation>false</generateApiDocumentation>
                <generateModelDocumentation>false</generateModelDocumentation>
                <generateModelTests>false</generateModelTests>
                <generateSupportingFiles>false</generateSupportingFiles>
                <language>jaxrs-spec</language>
                <importMappings>
                    <importMapping>
                        Scenario=com.bouygtel.postit.model.Scenario
                    </importMapping>
                    <importMapping>
                        Environment=com.bouygtel.postit.model.Environment
                    </importMapping>
                    <importMapping>
                        Job=com.bouygtel.postit.model.Job
                    </importMapping>
                </importMappings>
                <configOptions>
                    <useBeanValidation>true</useBeanValidation>
                    <performBeanValidation>true</performBeanValidation>
                    <java8>true</java8>
                    <useTags>true</useTags>
                    <sourceFolder>java</sourceFolder>
                </configOptions>
                <output>${project.build.directory}/generated-sources</output>
            </configuration>
        </execution>
        <execution>
            <id>generate-ts-client</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/api.yml</inputSpec>
                <generateApiTests>false</generateApiTests>
                <generateApiDocumentation>false</generateApiDocumentation>
                <generateModelDocumentation>false</generateModelDocumentation>
                <generateModelTests>false</generateModelTests>
                <generateSupportingFiles>true</generateSupportingFiles>
                <language>typescript-angular</language>
                <importMappings>
                    <importMapping>
                        Scenario=model/Scenario
                    </importMapping>
                    <importMapping>
                        Environment=model/Environment
                    </importMapping>
                </importMappings>
                <configOptions>
                    <ngVersion>7.1.0</ngVersion>
                </configOptions>
                <output>${project.basedir}/../gui/src/generated/client</output>
            </configuration>
        </execution>
    </executions>
</plugin>

I could not find any workaround.

Thanks
Sylros

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The issue names pom.xml and provides an OpenAPI YAML path plus Java and TypeScript generated snippets. Start by reproducing generation with swagger-codegen-maven-plugin 3.0.41 and the shown import mappings, then compare request signatures for imported and Swagger-defined body types. Done means imported request bodies appear in both generated implementations without regressing response mappings.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, typescript, yaml
Domain
api, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.