Viktor M.
Viktor M.

Reputation: 4613

Reactive REST API pagination

Faced with the problem of adding pagination to reactive REST API. Thought there is a way to add Pageable/PageRequest field to my request query object but it doesn't work in the way you will be able to define page/size as query parameters.

Only one working approach - define page and size as separate fields of request query object explicitly and then convert it to Pageable object using PageRequest.of().

The question: Do we have non-explicit way of adding pagination to reactive REST API endpoints as it works in Spring MVC using Pageable object as query parameter?

Controller:

...
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

@RestController
@RequestMapping("/foos")
@RequiredArgsConstructor
public class FooController {

    private final FooService fooService;

    @GetMapping
    @Validated
    public Mono<Page<Foo>> readCollection(FooCollectionQuery query) { // Also tried to define Pageable as separate parameter here, still not working
        return fooService.readCollection(query);
    }

}

Request query object:

...
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

@Value
@EqualsAndHashCode(callSuper = false)
public class FooCollectionQuery {

    @NotNull
    UUID id;

    ...

    // Pageable page; - not working
    // Page page; - not working
    // PageRequest page; - not working

}

The way I tried to call endpoint with pagination:

http://.../foos?page=1&size=2

Upvotes: 0

Views: 3061

Answers (1)

Viktor M.
Viktor M.

Reputation: 4613

Problem solved, since Spring WebFlux doesn't support pagination, I added custom resolver - ReactivePageableHandlerMethodArgumentResolver.

Here is example how I configure it:

@Configuration
public class WebConfig extends WebFluxConfigurationSupport {

    @Override
    protected void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
        configurer.addCustomResolver(new ReactivePageableHandlerMethodArgumentResolver());
        super.configureArgumentResolvers(configurer);
    }

}

And then I'm able to use pageable object in request query object:

@GetMapping
    @Validated
    public Mono<Page<Foo>> readCollection(FooCollectionQuery query, Pageable page) {
        return fooService.readCollection(query);
    }

Upvotes: 2

Related Questions