swagger-api / swagger-api/swagger-core

ArraySchema with anyOf is setting type of the items to "string"

Open
#4,624 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

backlog
Dominant language
Java
Stars
7.5k
Forks
2.3k
Avg merge
18h 1m
Merged PRs (30d)
10

Description

Hi!

I am using Spring Boot (3.2.3) with springdoc-openapi-starter-webmvc-ui (2.2.20). I have a controller annotated like this:

    @ApiResponse(responseCode = "200",
            content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                    array = @ArraySchema(schema = @Schema(anyOf = {
                            Dto1.class,
                            Dto2.class
                    }))))
    @GetMapping
    public List<? extends AbstractDto> get() {
        return List.of();
    }

This results in an API specification looking like this:

{
   "openapi": "3.0.1",
   "info": {
       "title": "OpenAPI definition",
       "version": "v0"
   },
   "servers": [
       {
           "url": "http://localhost:8080",
           "description": "Generated server url"
       }
   ],
   "paths": {
       "/": {
           "get": {
               "tags": [
                   "controller"
               ],
               "operationId": "get_1",
               "responses": {
                   "200": {
                       "description": "OK",
                       "content": {
                           "application/json": {
                               "schema": {
                                   "type": "array",
                                   "items": {
                                       "type": "string",
                                       "anyOf": [
                                           {
                                               "$ref": "#/components/schemas/Dto1"
                                           },
                                           {
                                               "$ref": "#/components/schemas/Dto2"
                                           }
                                       ]
                                   }
                               }
                           }
                       }
                   }
               }
           }
       }
   },
   "components": {
       "schemas": {
           "Dto1": {
               "type": "object"
           },
           "Dto2": {
               "type": "object"
           }
       }
   }
}

As you can see the type of the items in the array is set to string which looks wrong and also results in swagger-ui rendering the API wrong.
Tracking the code led me to this line which sets the type to "string":
https://github.com/swagger-api/swagger-core/blob/3fcc473c33c56f306902853a451020926ad691ea/modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java#L1745

I don't really understand why this is done. As a workaround to get it working correctly I added an explicit type to the items like this which atleast makes swagger-ui render the anyOf correctly:

    @ApiResponse(responseCode = "200",
            content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                    array = @ArraySchema(schema = @Schema(anyOf = {
                            Dto1.class,
                            Dto2.class
                    }, type = "object"))))
    @GetMapping
    public List<? extends AbstractDto> get() {
        return List.of();
    }

What I would have expected in the first place is that the type is not added to the items at all if an anyOf is included.

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 in modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java around line 1745 and read the surrounding schema handling for ArraySchema and anyOf. Reproduce the reported annotation case, then verify that generated array items no longer receive a string type when anyOf is present, while the explicit type workaround remains unnecessary.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring-boot
Domain
api
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.