Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG][SPRING] multipart/form with optional parameters does not produce "Optional" in API interface, only in API Delagate #9530

Open
4 of 5 tasks
sparmboy opened this issue May 20, 2021 · 1 comment · May be fixed by #20793

Comments

@sparmboy
Copy link

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • [] Have you tested with the latest master to confirm the issue still exists? (Blocked by corporate firewall unfortunately)
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When defining an endpoint that consumes multipart/form-data that contains optional parameters, the generated XXXApi.java interface class does not produce a parameter wrapped in Optional whereas the accompanying XXXXApiDelegate.java does, thus where the Api calls the Delegate, the compiler rightly throws the error:

incompatible types: java.lang.String cannot be converted to java.util.Optional<java.lang.String>

Generated API

  default ResponseEntity<Void> upload(
@ApiParam(value = "", required=true) @Valid @RequestPart(value = "name", required = true)  String name,
@ApiParam(value = "") @Valid @RequestPart(value = "data", required = true) MultipartFile data,
@ApiParam(value = "") @Valid @RequestPart(value = "description", required = false)  String description) {
        return getDelegate().upload(name, data, description);
    }

Generated API Delegate

    default ResponseEntity<Void> upload(String name,
        MultipartFile data,
        Optional<String> description) {
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);

    }
openapi-generator version

5.1.1

swagger version

2.0

OpenAPI declaration file content or url
{
  "swagger": "2.0",
  "info": {
    "description": "Example swagger definition for an application API",
    "version": "1.0.0-SNAPSHOT",
    "title": "App Template"
  },
  "host": "localhost:8080",
  "tags": [
    {
      "name": "test-controller"
    }
  ],
  "paths": {
    "/templates": {
      "post": {
        "tags": [
          "test-controller"
        ],
        "summary": "Upload",
        "operationId": "upload",
        "consumes": [
          "multipart/form-data"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "in": "body",
            "name": "uploadRequest",
            "required": true,
            "schema":{
              "type": "object",
              "title": "UploadRequest",
              "required": [
                "name",
                "data"
              ],
              "properties": {
                "name": {
                  "type": "string"
                },
                "data": {
                  "type": "string",
                  "format": "binary"
                },
                "description": {
                  "type": "string"
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "deprecated": false
      }
    }
  }
}

pom

<?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 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>


    <parent>
        <artifactId>spring-boot-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.1.1.RELEASE</version>
    </parent>
    <artifactId>open-api-bug</artifactId>
    <name>0.0.1</name>

    <properties>
        <java.version>1.8</java.version>
        <openapi-generator-maven-plugin.version>5.1.1</openapi-generator-maven-plugin.version>
        <springfox-version>2.9.2</springfox-version>
        <swagger.version>1.5.21</swagger.version>
    </properties>

    <dependencyManagement>
        <dependencies>

        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.fasterxml</groupId>
                    <artifactId>classmate</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-spring-web</artifactId>
            <version>${springfox-version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springfox-version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${springfox-version}</version>
            <exclusions>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-models</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-commons</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>
        <dependency>
            <groupId>org.openapitools</groupId>
            <artifactId>jackson-databind-nullable</artifactId>
            <version>0.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>${hibernate-validator.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
        </dependency>
    </dependencies>


    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>${openapi-generator-maven-plugin.version}</version>
                <executions>

                    <!-- Generate the spring controllers -->
                    <execution>
                        <id>generate-java</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${basedir}/swagger.json</inputSpec>
                            <generatorName>spring</generatorName>
                            <ignoreFileOverride>${project.basedir}/.openapi-generator-ignore</ignoreFileOverride>
                            <modelPackage>${project.groupId}.model</modelPackage>
                            <apiPackage>${project.groupId}.controllers</apiPackage>
                            <generateModels>true</generateModels>
                            <configOptions>
                                <basePackage>${project.groupId}</basePackage>
                                <configPackage>${project.groupId}.config</configPackage>
                                <java8>true</java8>
                                <dateLibrary>java8</dateLibrary>
                                <performBeanValidation>true</performBeanValidation>
                                <useTags>true</useTags>
                                <useOptional>true</useOptional>
                                <generateApiTests>true</generateApiTests>
                                <generateApiDocumentation>false</generateApiDocumentation>
                                <supportingFiles>false</supportingFiles>
                                <serializableModel>true</serializableModel>
                                <delegatePattern>true</delegatePattern>
                                <supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
                            </configOptions>
                            <additionalProperties>name=value</additionalProperties>

                        </configuration>
                    </execution>

                </executions>
            </plugin>

        </plugins>
    </build>
</project>
Generation Details

Run:

mvn clean compile
Steps to reproduce

Run:

mvn clean compile
Related issues/PRs
Suggest a fix

Need to have the API define optional parameters as Optional

@fc-smohr
Copy link

This case with useOptional=true and delegatePattern=true generates this error. If one of this switches is set to false, the compilation is successful.
We are running into the same issue.
Does anyone have a better workaround?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants