Describe the bug My app is an Spring boot API using these versions : Spring-cloud-openfeign-core : 3.1.5 Spring-data-commons : 2.7.6
I am using a feign client with an endpoint returning a Page<ClientDTO> like this example :
import org.springframework.data.domain.Page;
/* others imports */
@FeignClient(name = "SpringRemoteApiClient ", url = "${api.spring-remote.url}/users", configuration = FeignConfig.class)
public interface SpringRemoteApiClient {
@GetMapping(value = "/country/{country}")
Page<ClientDTO> getClientsByCountry(@PathVariable("country") String country, @ParameterObject @PageableDefault(sort = "name") Pageable pageable);
}
This feign client is a Spring boot OpenAPI application (Spring boot 2.7.6).
If I call directly the endpoint, the JSON reponse will have this structure :
{
"content": [
{
"id": 1,
"name": "Abc",
"country": "Def"
},
...
],
"pageable": {
"page": 0,
"size": 10,
"sort": {
"orders": [
{
"direction": "ASC",
"property": "client.name",
"ignoreCase": false,
"nullHandling": "NATIVE",
"ascending": true,
"descending": false
}
],
"empty": false,
"sorted": true,
"unsorted": false
},
"unpaged": false,
"paged": true
},
"total": 34,
"last": true,
"first": false,
"empty": false
}
And when I call the endpoint with feign, the response is decoded by org.springframework.cloud.openfeign.support.PageJacksonModule
What I get :
Page<ClientDTO> clients = springRemoteApiClient.getClientsByCountry(country, PageRequest.of(0, 10));
clients.getTotalElements(); // 10
clients.getSize(); // 10
clients.getTotalPages(); // 1
clients.getSort().isSorted(); // false
clients.isLast(); // true
What I want :
Page<ClientDTO> clients = springRemoteApiClient.getClientsByCountry(country, PageRequest.of(0, 10));
clients.getTotalElements(); // 34
clients.getSize(); // 10
clients.getTotalPages(); // 4
clients.getSort().isSorted(); // true
clients.isLast(); // false
The response is then incomplete, only content match with SimplePageImpl constructor. Other attributes gets a wrong default value.
The issue is that PageJacksonModule doesn't fullfill number, size, totalElementsor sortattributes in SimplePageImpl constructor as you can see here :
/* part of PageJacksonModule */
SimplePageImpl(@JsonProperty("content") List<T> content, @JsonProperty("number") int number, @JsonProperty("size") int size, @JsonProperty("totalElements") @JsonAlias({"total-elements", "total_elements", "totalelements", "TotalElements"}) long totalElements, @JsonProperty("sort") Sort sort) {
if (size > 0) {
PageRequest pageRequest;
if (sort != null) {
pageRequest = PageRequest.of(number, size, sort);
} else {
pageRequest = PageRequest.of(number, size);
}
this.delegate = new PageImpl(content, pageRequest, totalElements);
} else {
this.delegate = new PageImpl(content);
}
}
Do you have any solution or is it possible to fix this issue in a future release ?
By adding @JsonProperty("pageable") JsonNode pageable, and @JsonAlias({"total",...}) in the SimplePageImpl constructor for example ?
Thank you,
Comment From: OlgaMaciaszek
Hi @AlexyNau, thanks for reporting this issue. Can you please provide a sample as a link to a small executable app that reproduces the issue instead of separate code snippets? - we'll take a closer look then.
Comment From: AlexyNau
Hello @OlgaMaciaszek, you can find a sample in my repositories. First, a backend api that is used as a feign client : https://github.com/AlexyNau/my-app And then, the bff api, where you can reproduce the issue : https://github.com/AlexyNau/bff-my-app Clone them both and launch them as a SpringBoot Application (JDK 19). Feel free if you have any questions.
Comment From: OlgaMaciaszek
Thanks for the sample @AlexyNau. I was able to reproduce it. Will provide a fix.
Comment From: ffroliva
Any update on this?
Comment From: aliemredeneri
Any news ?
Comment From: OlgaMaciaszek
Fix merged to main. Will be available with the next 2023.0.x Spring Cloud release.