swagger-api / swagger-api/swagger-codegen

[SPRING][SPRING-CLOUD] Bug generating server code response content type when multiple content type are present

Open
#12,322 0 comments 0 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

Description

Wrong server code is generated when using multiple content types for different http response codes:

@Validated
@Api(value = "Default", description = "the Default API")
public interface DefaultApi {

     /** ... **/

    @ApiOperation(value = "", nickname = "exportUsers", notes = "", response = byte[].class, tags={  })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "Successful operation", response = byte[].class),
        @ApiResponse(code = 500, message = "Internal server error", response = InlineResponse500.class) })
    @RequestMapping(value = "/api/v1/export/users",
        produces = "application/json", 
        method = RequestMethod.GET)
    default ResponseEntity<byte[]> exportUsers() { /** ... **/ }
}

What I am expecting is that @RequestMapping should not define "produces" field, while @ApiResponse should declare a different Content for every response code.

Swagger-codegen version

swagger-codegen-maven-plugin 3.0.52

Swagger declaration file content or url
openapi: 3.0.3
info:
  title: Spring cloud codegen bug
  version: 1.0.0
paths:
  /api/v1/export/users:
    get:
      operationId: exportUsers
      responses:
        '200':
          description: Successful operation
          content:
            application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:
              schema:
                type: string
                format: byte
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  reason:
                    type: string
                  description:
                    type: string
Command line used for generation
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>my-library</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <spring-boot.version>3.2.1</spring-boot.version>
        <spring-cloud.version>2023.0.0</spring-cloud.version>
        <jackson.version>2.15.3</jackson.version>
        <swagger-codegen-plugin.version>3.0.52</swagger-codegen-plugin.version>

        <openapi.package>${project.groupId}.library</openapi.package>
        <openapi.model.package>${openapi.package}.api</openapi.model.package>
        <openapi.client.package>${openapi.package}.client</openapi.client.package>
        <openapi.invoker.package>${openapi.package}.invoker</openapi.invoker.package>
        <openapi.file.name>api.yaml</openapi.file.name>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-security</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.5.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.oltu.oauth2</groupId>
            <artifactId>org.apache.oltu.oauth2.client</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.16.0</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.6.12</version>
        </dependency>
        <dependency>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>2.2.19</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-jackson</artifactId>
            <version>13.1</version>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>io.swagger.codegen.v3</groupId>
                    <artifactId>swagger-codegen-maven-plugin</artifactId>
                    <version>${swagger-codegen-plugin.version}</version>
                    <executions>
                        <execution>
                            <id>java-model-generation</id>
                            <phase>generate-sources</phase>
                            <goals>
                                <goal>generate</goal>
                            </goals>
                            <configuration>
                                <language>spring</language>
                                <library>spring-cloud</library>
                                <generateApis>true</generateApis>
                                <generateSupportingFiles>true</generateSupportingFiles>
                                <inputSpec>${project.basedir}/src/main/resources/${openapi.file.name}</inputSpec>
                                <output>${project.build.directory}/generated-sources/swagger</output>
                                <modelPackage>${openapi.model.package}</modelPackage>
                                <apiPackage>${openapi.client.package}</apiPackage>
                                <invokerPackage>${openapi.invoker.package}</invokerPackage>
                                <configOptions>
                                    <generateForOpenFeign>true</generateForOpenFeign>
                                    <dateLibrary>java8</dateLibrary>
                                    <sourceFolder>src/main/java</sourceFolder>
                                    <hideGenerationTimestamp>true</hideGenerationTimestamp>
                                    <annotationLibrary>swagger3</annotationLibrary>
                                    <serializableModel>true</serializableModel>
                                    <serializationLibrary>jackson</serializationLibrary>
                                    <additionalEnumTypeAnnotations>true</additionalEnumTypeAnnotations>
                                    <useJakartaEe>true</useJakartaEe>
                                    <useSpringBoot3>true</useSpringBoot3>
                                    <useEnumCaseInsensitive>true</useEnumCaseInsensitive>
                                </configOptions>
                                <typeMappings>
                                    <typeMapping>Double=java.math.BigDecimal</typeMapping>
                                </typeMappings>
                                <importMappings>
                                    <importMapping>GregorianCalendar=java.util.GregorianCalendar</importMapping>
                                </importMappings>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>
            <plugin>
                <groupId>io.swagger.codegen.v3</groupId>
                <artifactId>swagger-codegen-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
Steps to reproduce

Create a maven project with the following directory structure:

my-library
├── pom.xml
├── src
    ├── main
        ├── resources
            ├── api.yaml

Run:

mvn install

And check ./$OUTPUT_DIR/generated-sources/swagger/src/main/java/com/example/library/client/DefaultApi.java

Suggest a fix/enhancement

This bug probably happens because the wrong version of @ApiResponse is being used for generating the server code. As a matter of fact both io.swagger.swagger-annotations and io.swagger.core.v3.swagger-annotations need to be imported.

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

Start by running mvn install with the provided pom.xml and src/main/resources/api.yaml, then inspect the generated DefaultApi.java under generated-sources/swagger. Compare the generated @RequestMapping and response annotations with the issue's expected per-response content types; done means the output preserves the distinct response content types without an incorrect produces value.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, openapi
Domain
backend, 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.