Search code examples
springspring-bootcompletable-future

Return results as CompletableFutures completes?


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?


Solution

  • 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