Search code examples
springspring-dataspring-cloudspring-cloud-feignfeign

Spring Data Pageable not supported as RequestParam in Feign Client


I have been trying to expose a Feign Client for my rest api. It takes Pageable as input and has PageDefaults defined.

Controller:

@GetMapping(value = "data", produces = MediaType.APPLICATION_JSON_VALUE)
@ApiOperation(value = "Get Data", nickname = "getData")
public Page<Data> getData(@PageableDefault(size = 10, page = 0) Pageable page,
            @RequestParam(value = "search", required = false) String search) {
    return service.getData(search, page);
}

And here is my feign client:

@RequestMapping(method = RequestMethod.GET, value = "data")
public Page<Data> getData(@RequestParam(name = "pageable", required = false) Pageable page,
            @RequestParam(name = "search", defaultValue = "null", required = false) String search);

Now the problem is regardless of whatever page size and page number I send to Feign Client it always applies PageDefaults (0,10).

When I call the rest service directly it works: http://localhost:8080/data?size=30&page=6

I am using Spring Boot 2.1.4.RELEASE and Spring Cloud Greenwich.SR1. Recently a fix was done to support Pageable (https://github.com/spring-cloud/spring-cloud-openfeign/issues/26#issuecomment-483689346). However I am not sure it the above scenario is not covered or I am missing something.


Solution

  • I think your code doesn't work because you are using @RequestParam annotation for Pageable parameter in your Feign method.

    My implementation of such a method works as expected.

    Client:

    @FeignClient(name = "model-service", url = "http://localhost:8080/")
    public interface ModelClient {
        @GetMapping("/models")
        Page<Model> getAll(@RequestParam(value = "text", required = false) String text, Pageable page);
    }
    

    Controller:

    @GetMapping("/models")
    Page<Model> getAll(@RequestParam(value = "text", required = false, defaultValue = "text") String text, Pageable pageable) {
        return modelRepo.getAllByTextStartingWith(text, pageable);
    }
    

    Note that in my case, without exposing PageJacksonModule as a bean, Spring raised the exception:

    InvalidDefinitionException: Cannot construct instance of org.springframework.data.domain.Page

    So I had to add it to the project:

    @Bean
    public Module pageJacksonModule() {
        return new PageJacksonModule();
    }
    

    My working demo: github.com/Cepr0/sb-feign-client-with-pageable-demo