I have a Spring Boot web application that takes a string as a GET request. The application then generates a list of text from the keyword in their own thread then returns a CompletableFuture.
Some threads may take 30 seconds to complete, other maybe less than a second.
Is it possible for the controller to return the result of each thread as they get completed to the calling client?
Yes, you can return CompletableFuture<>
or a List<CompletableFuture<>>
as they are finished.
Spring delivers a starter project 'org.springframework.boot:spring-boot-starter-webflux'
that allows you to write non-blocking, reactive controllers.
So, provided that you have a list of CompletableFuture<>
as the result of texts generations, your controller should look like this:
@GetMapping(path = "/test")
public Flux<String> getListReactively2(@RequestParam String keyword) {
List<CompletableFuture<String>> completableFutures = getCompletableFutures(keyword);
List<Mono<String>> monos = completableFutures.stream().map(Mono::fromFuture).toList();
return Flux.fromIterable(monos).flatMap(Function.identity());
}
The List of CompletableFuture<>
is mapped to Flux<String
which is the spring-webflux
type that represents a Stream of objects that will be returned as the objects are delivered in the stream.
For more information, refer to spring webflux documentation https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html