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

[JAVA][SPRING] Arrays are not rendered correctly in responses #14178

Closed
superplan opened this issue Dec 5, 2022 · 11 comments
Closed

[JAVA][SPRING] Arrays are not rendered correctly in responses #14178

superplan opened this issue Dec 5, 2022 · 11 comments

Comments

@superplan
Copy link

Description

Objects of type "array" are not rendered correctly in responses, see example below. The UI shows only an item of the array, which is misleading.

openapi-generator version

6.2.1

OpenAPI declaration file content or url
openapi: 3.0.3
info:
  version: 1.0.0
  title: See, thats an array!
  description: An example to demonstrate how array responses are rendered in Swagger-UI.
paths:
  /free-donuts:
    get:
      description: Process data
      operationId: getDonuts
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Donut'
components:
  schemas:
    Donut:
      type: object
      required:
        - menuName
      properties:
        name:
          type: string
          description: key
        glazed:
          type: boolean
          description: value
Command line used for generation

java -jar openapi-generator-cli-6.2.1.jar generate -g spring -i input.yaml -o "spring_6.2.1" -c config.yaml

Here is my config.yaml:

additionalProperties:
  useTags: true
  java8: true
  useOptional: true
  useBeanValidation: true
  delegatePattern: true

Produces:
image

Expect:
image

Steps to reproduce

Generate spring-Server und run as java application. Schema for the response code 200 is "Donut" and not an array of "Donut".

Related issues/PRs
Suggest a fix/enhancement

Incorporate @ArraySchema into api.mustache. Here the fix is code enclosed by tag "{{#isArray}}":

...
import io.swagger.v3.oas.annotations.media.ArraySchema;
...
        responses = {
            {{#responses}}
            @ApiResponse(responseCode = "{{{code}}}", description = "{{{message}}}"{{#baseType}}, content = {
                {{#produces}}
                @Content(mediaType = "{{{mediaType}}}", {{#isArray}}array = @ArraySchema( {{/isArray}}schema = @Schema(implementation = {{{baseType}}}.class)){{#isArray}}){{/isArray}}{{^-last}},{{/-last}}
                {{/produces}}
            }{{/baseType}}){{^-last}},{{/-last}}
            {{/responses}}
        }

Now the DefaultApi.java should look like this:

...
    @ApiResponses(value = { 
        @ApiResponse(responseCode = "200", description = "Successful response", content = @Content(
        		mediaType = "application/json", 
        		array = @ArraySchema(schema = @Schema(implementation = DonutBox.class))
        		))
        })
...

Instead of:

...
    @ApiResponses(value = { 
        @ApiResponse(responseCode = "200", description = "Successful response", content = @Content(
        		mediaType = "application/json", 
        		schema = @Schema(implementation = DonutBox.class)
        		))
        })
...
@Bsd15
Copy link

Bsd15 commented Dec 6, 2022

For me, in the generated API class the return type is set to ResponseEntity<Object> which is causing swagger to render empty response.

openapi: 3.1.0
info:
  title: Cats API
  version: 0.1.0
  summary: API for Cats
  description: Practice project for OpenAPI specification
paths:
  /cats:
    post:
      description: Add a new cat
      summary: Add a cat
      operationId: addCat
      requestBody:
        description: Request for creating a new cat
        content:
          'application/json':
            schema:
              $ref: '#/components/schemas/Cat'
      responses:
        '201':
          description: Cat has been added successfully.
    get:
      description: Get all cats
      summary: Get Cats
      operationId: getCats
      responses:
        '200':
          description: Cats response
          content:
            'application/json':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Cat'
components:
  schemas:
    Cat:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
        status:
            type: string
            enum:
              - available
              - adopted
              - dead

CatsAPI.java

    /**
     * GET /cats : Get Cats
     * Get all cats
     *
     * @return Cats response (status code 200)
     */
    @Operation(
        operationId = "getCats",
        summary = "Get Cats",
        responses = {
            @ApiResponse(responseCode = "200", description = "Cats response", content = {
                @Content(mediaType = "application/json", schema = @Schema(implementation = Object.class))
            })
        }
    )
    @RequestMapping(
        method = RequestMethod.GET,
        value = "/cats",
        produces = { "application/json" }
    )
    default ResponseEntity<Object> getCats(
        
    ) {
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);

    }

POM.xml

<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.2.1</version>
<!-- /RELEASE_VERSION -->
<executions>
	<execution>
		<goals>
			<goal>generate</goal>
		</goals>
		<configuration>
			<inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec>
			<generatorName>spring</generatorName>
			<configOptions>
				<sourceFolder>src/gen/java/main</sourceFolder>
				<interfaceOnly>true</interfaceOnly>
			</configOptions>
		</configuration>
	</execution>
</executions>
</plugin>

image

@ataylormays-duetto
Copy link

My team is facing the same issue.

@borsch
Copy link
Member

borsch commented Dec 7, 2022

For me, in the generated API class the return type is set to ResponseEntity<Object> which is causing swagger to render empty response.

openapi: 3.1.0
info:
  title: Cats API
  version: 0.1.0
  summary: API for Cats
  description: Practice project for OpenAPI specification
paths:
  /cats:
    post:
      description: Add a new cat
      summary: Add a cat
      operationId: addCat
      requestBody:
        description: Request for creating a new cat
        content:
          'application/json':
            schema:
              $ref: '#/components/schemas/Cat'
      responses:
        '201':
          description: Cat has been added successfully.
    get:
      description: Get all cats
      summary: Get Cats
      operationId: getCats
      responses:
        '200':
          description: Cats response
          content:
            'application/json':
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Cat'
components:
  schemas:
    Cat:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
        status:
            type: string
            enum:
              - available
              - adopted
              - dead

CatsAPI.java

    /**
     * GET /cats : Get Cats
     * Get all cats
     *
     * @return Cats response (status code 200)
     */
    @Operation(
        operationId = "getCats",
        summary = "Get Cats",
        responses = {
            @ApiResponse(responseCode = "200", description = "Cats response", content = {
                @Content(mediaType = "application/json", schema = @Schema(implementation = Object.class))
            })
        }
    )
    @RequestMapping(
        method = RequestMethod.GET,
        value = "/cats",
        produces = { "application/json" }
    )
    default ResponseEntity<Object> getCats(
        
    ) {
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);

    }

POM.xml

<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>6.2.1</version>
<!-- /RELEASE_VERSION -->
<executions>
	<execution>
		<goals>
			<goal>generate</goal>
		</goals>
		<configuration>
			<inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec>
			<generatorName>spring</generatorName>
			<configOptions>
				<sourceFolder>src/gen/java/main</sourceFolder>
				<interfaceOnly>true</interfaceOnly>
			</configOptions>
		</configuration>
	</execution>
</executions>
</plugin>
image

change openapi version to '3.0.0' instead of '3.1.0'. seems like there are some changes on parser change which affect you. I'll create separate issue for this since this is global code update

@superplan
Copy link
Author

When using openapi version '3.1.0' the tag {{{baseType}}} is returned as "Object". In my example (see Issue description) this generates:

@Content(mediaType = "application/json", schema = @Schema(implementation = Object.class))

in the response method (DefaultApi.java), which is now a double bug. First you need:

@Content(mediaType = "application/json", schema = @Schema(implementation = Donut.class))

to avoid an empty response. Secondly, the final result should be

@Content(mediaType = "application/json", array = @ArraySchema( schema = @Schema(implementation = Donut.class)))

with regards to the array nature of the response object.

Just confirming that theses are two separate problems, as described in #14200. Thanks @borsch!

@borsch
Copy link
Member

borsch commented Jan 13, 2023

@superplan please try latest 6.3.0-SNAPSHOT

@superplan
Copy link
Author

Using 6.3.0-SNAPSHOT (Build from Fri Jan 13 14:03:03 UTC 2023) it works with openapi versions 3.0.0, 3.0.1, 3.0.2 and 3.0.3. Thanks @borsch!
For openapi version 3.1.0 an empty response is generated.

@borsch
Copy link
Member

borsch commented Jan 13, 2023

@superplan 3.1.0 is not unsupported as for now so it's a kind of expected result

@superplan
Copy link
Author

That's fine with me. The issue can be closed now, since it will be resolved with generator version 6.3.0.

@bjorgvino
Copy link
Contributor

bjorgvino commented Jan 20, 2023

Has version 6.3.0 gotten a release date yet? I'm running into this issue using 6.2.1. I tested 6.3.0-SNAPSHOT and it does fix the array response issue, but I'm getting compilation errors in some generated models instead.

cannot find symbol
[ERROR]   symbol:   method requiredMode()
[ERROR]   location: @interface io.swagger.v3.oas.annotations.media.Schema

image

Update:
Updating swagger.annotations version from 1.6.6 to 2.2.8 (groupId io.swagger -> io.swagger.core.v3) fixes the cannot find symbol related to requiredMode. But the generated code still has compilation errors:

cannot find symbol
[ERROR]   symbol:   method get(int)
[ERROR]   location: interface java.util.Set<>

image

That field is an array with uniqueItems: true so it will become a Set<> here, and sets don't provide a .get() method...

This is in the public String toUrlQueryString(String prefix) method which seems to always be generated, even though supportUrlQuery is not present or is disabled: <additionalProperties>supportUrlQuery=false</additionalProperties>
That's a bug I think, I'll try to go ahead and fix that...just need to figure out the process :)

Saw that the 6.3.0 release is being prepared, nice! 👌🏼 #14491

@bjorgvino
Copy link
Contributor

The issue above is fixed by #14496 (6.3.0 release).

@RisteJovanoski
Copy link

In version 6.6.0 the method toUrlQueryString is always generated, even though supportUrlQuery is not present or is disabled: <configOptions><supportUrlQuery>false</supportUrlQuery></configOptions>. Shouldn't this config option stop the generator from generating this method?

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

No branches or pull requests

6 participants