swagger-api / swagger-api/swagger-core
ArraySchema with anyOf is setting type of the items to "string"
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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