'How to link a Vaadin Grid with the result of Spring Mono WebClient data

This seems to be a missing part in the documentation of Vaadin...

I call an API to get data in my UI like this:

@Override
public URI getUri(String url, PageRequest page) {
    return UriComponentsBuilder.fromUriString(url)
            .queryParam("page", page.getPageNumber())
            .queryParam("size", page.getPageSize())
            .queryParam("sort", (page.getSort().isSorted() ? page.getSort() : ""))
            .build()
            .toUri();
}

@Override
public Mono<Page<SomeDto>> getDataByPage(PageRequest pageRequest) {
    return webClient.get()
            .uri(getUri(URL_API + "/page", pageRequest))
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference<>() {
            });
}

In the Vaadin documentation (https://vaadin.com/docs/v10/flow/binding-data/tutorial-flow-data-provider), I found an example with DataProvider.fromCallbacks but this expects streams and that doesn't feel like the correct approach as I need to block on the requests to get the streams...

DataProvider<SomeDto, Void> lazyProvider = DataProvider.fromCallbacks(
     q -> service.getData(PageRequest.of(q.getOffset(), q.getLimit())).block().stream(),
     q -> service.getDataCount().block().intValue()
);

When trying this implementation, I get the following error:

org.springframework.core.codec.CodecException: Type definition error: [simple type, class org.springframework.data.domain.Page]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.springframework.data.domain.Page` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 1]
grid.setItems(lazyProvider);


Solution 1:[1]

There are two parts to this question.

The first one is about asynchronously loading data for a DataProvider in Vaadin. This isn't supported since Vaadin has prioritized the typical case with fetching data straight through JDBC. This means that you end up blocking a thread while the data is loading. Vaadin 23 will add support for doing that blocking on a separate thread instead of keeping the UI thread blocked, but it will still be blocking.

The other half of your problem doesn't seem to be directly related to Vaadin. The exception message says that the Jackson instance used by the REST client isn't configured to support creating instances of org.springframework.data.domain.Page. I don't have direct experience with this part of the problem, so I cannot give any advice on exactly how to fix it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Leif Åstrand