Mismatch between `org.springframework.data.domain.Page<ItemDto>` and the openapi spec
aconrad opened this issue · comments
Describe the bug
When my controller returns Page<...>
, the JSON response has the keys content
(containing the paged items) and page
(containing the pageable info) but the openapi spec shows a different schema with keys such as content
(as expected) but also pageable
, totalElements
, totalPages
, first
, last
, etc... (see full list below). This started happening when I upgraded org.springframework.boot
from 3.2.6 to 3.3.0.
Why doesn't the openapi spec reflect the returned data?
To Reproduce
Steps to reproduce the behavior:
- What version of spring-boot you are using?
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
- What modules and versions of springdoc-openapi are you using?
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
- What is the actual and the expected result using OpenAPI Description (yml or json)?
The openapi output (JSON, only the relevant part):
"PageItemDto": {
"type": "object",
"properties": {
"totalElements": {
"type": "integer",
"format": "int64"
},
"totalPages": {
"type": "integer",
"format": "int32"
},
"first": {
"type": "boolean"
},
"last": {
"type": "boolean"
},
"size": {
"type": "integer",
"format": "int32"
},
"content": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ItemDto"
}
},
"number": {
"type": "integer",
"format": "int32"
},
"sort": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"numberOfElements": {
"type": "integer",
"format": "int32"
},
"pageable": {
"$ref": "#/components/schemas/PageableObject"
},
"empty": {
"type": "boolean"
}
}
},
- Provide with a sample code (HelloController) or Test that reproduces the problem
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
@GetMapping("/my-endpoint")
public Page<ItemDto> getItems(
@ParameterObject @PageableDefault(page = 0, size = 10) Pageable pageable) {
// ...
return new PageImpl<>(items, pageable, dbObjects.getTotalElements());
}
The data returned by the controller:
{
"content": [
{
// serialized ItemDto
},
// ...
],
"page": {
"size": 10,
"number": 0,
"totalElements": 48,
"totalPages": 5
}
}
Expected behavior
- A clear and concise description of what you expected to happen.
I expect the JSON output to describe PageItemDto with only 2 keys, content
and page
.
- What is the expected result using OpenAPI Description (yml or json)?
Something like this (handcrafted, sorry if typos):
"PageItemDto": {
"type": "object",
"properties": {
"content": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ItemDto"
}
},
"page": {
"$ref": "#/components/schemas/Page"
}
}
},
"Page": {
"type": "object",
"properties": {
"totalElements": {
"type": "integer",
"format": "int64"
},
"totalPages": {
"type": "integer",
"format": "int32"
},
"size": {
"type": "integer",
"format": "int32"
},
"content": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ItemDto"
}
},
"number": {
"type": "integer",
"format": "int32"
},
},
Screenshots
If applicable, add screenshots to help explain your problem.
org.springframework.boot 3.3.0:
org.springframework.boot 3.2.6:
Additional context
Add any other context about the problem here.