Search code examples
javaspring-bootparallel-processingspring-webclient

Spring Boot 2 - WebClient : Call Multiple Rest API's from one Controller


I am using Spring Boot Micro Services and calling downstream to get the data.

The requirement is to get data from more than one downstream and aggregate the responses to a single response.

Could someone help how can I make parallel rest calls within a Get Request.

Below is the simple approach where I can call one after the other that. However, I am looking for parallel call.

@RestController
Class{

@GetMapping
method(){
    req1 = endpoint1;
    req2 = endpoint2;

    response = req1+req2; //How to achieve this using parallel processing.
}

Please assist. Thanks.


Solution

  • There is many ways how you can achieve parallel execution.

    One way might be using Streams:

    // First prepare tasks you want to run in parallel
    List<Supplier<Result>> tasks = new ArrayList<>();
    tasks.add(() -> {
        Result result = // get result from WebClient
        return result;
    });
    
    // Next execute in parallel all tasks and collect results
    List<Result> results = tasks.parallelStream()
            .map(Supplier::get)
            .collect(Collectors.toList());
    
    // Merge results into one
    

    Of if you would to have finer control over threads (how many tasks can run in parallel at once, to not have to spawn new threads for every endpoint call etc), then since you are using Spring Boot you might use eg. AsyncTaskExecutor

    class MyAwesomeController {
        private final AsyncTaskExecutor executor;
    
        public MyAwesomeController() {
            executor = new TaskExecutorBuilder()
                    .corePoolSize(5) // how many threads to keep alive
                    .maxPoolSize(20) // how many max threads (taks) can be executed at one
                    // Some other settings (eg. how long to keep idle thread alive etc.
                    .build();
        }
    
        public Result endpoint() {
            // First prepare tasks you want to run in parallel
            List<Future<Result>> tasks = new ArrayList<>();
            tasks.add(executor.submit(() -> {
                Result result = // get result from WebClient
                return result;
            }));
    
            // Next collect results from Future
            List<Result> results = tasks.stream()
                    .map(Future::get)
                    .collect(Collectors.toList());
            
            // Merge results into one
        }
    
    }
    

    More info on executors you can find eg. here: https://www.baeldung.com/java-executor-service-tutorial