Does the following code block the call, if so how do I make it non-blocking? i.e. making the use of Reactive Java Stream useless? How can I paginate without making the call blocking?
Currently I have a webClient calling to a backend service that returns a Flux<Item>
and according to specs I need to return a ResponseEntity<ItemListResponse>
where I have provide a paginated response
code inside the controller method looks like ->
// getItems method was initially returning a Flux but my method was failing to paginate it so now that method returns a Mono<List<Item>>
// I would really like to see how I can make this work with Flux!
return webClient.getItems(...required params...)
.map(r -> {
// we get offset and limit from query params
var paginatedItems = listPaginator.applyPagination(r, offset, limit)
// assembleItemResponse method maps all values from backend service to new response required by client
List<ItemResponse> itemResponseList = paginatedItems.stream()
.map(this::assembleItemResponse)
.collect(Collectors.toList());
return ResponseEntity.ok()
.body(ItemListResponse.builder()
.itemCount(r.size())
.pagesize(itemResponseList.size())
.listItems(itemResponseList)
.build());
});
Does applying Pagination on response using Spring Webflux make it blocking?
There's nothing inherently blocking about pagination, but the normal Spring Data way to achieve that is by using a PagingAndSortingRepository
to query the data layer for only the results you need for that particular page (as oppose to querying the data layer for all possible results then filtering, which could have a huge performance impact depending on the data size.) Unfortunately that approach is blocking. The PagingAndSortingRepository
doesn't as of yet have a reactive equivalent.
However, that doesn't appear to be what you're doing here. A complete example here would be helpful, but it looks like r
is a list of items, and then you're applying a listPaginator to that entire list to reduce it down. If that's the case then there's no reason why it would necessarily be blocking, so it should be safe. However, it's impossible to say for certain without knowing the specific behaviour of the applyPagination
and assembleItemResponse
methods. If those methods are blocking then no - you're not safe here, and you need to consider another approach (exactly what approach would require a more complete example.) If those methods are non-blocking (they just deal with the data they have, don't call any further web / db services, etc.) then you're ok.
Separately, you might consider looking at Blockhound which will be able to tell you for certain whether you have any blocking calls where they shouldn't be.