spring-bootspring-webfluxproject-reactornonblockingspring-reactive

Combining non-blocking and blocking calls and returning the results in Spring Webflux


I am using Spring Webflux along with Spring boot 2 and my scenario goes like this:

Controller

@GetMapping(path="/products")
public List<Products> getProducts(){
 return serviceObj.getProducts();
}

Service Class

public List<Products> getProducts(){
List<Products> products = null;
  //Call 1 -> to repository class method returning Flux<Products>
repositoryObj.getProductsFlux();
  //Call 2 -> To repository class method returning List<Products>
repositoryObj.getProductsNormal();
  //Concat results from Call 1 & Call 2 and return List<Products>
return products;
}

How can I concatenate results from a Flux & normal list of products before returning? Is it possible without having a Reactive Controller ?

P.S. I don't want to call .block() and CompleteableFuture on the results obtained from Call 1


Solution

  • There is no way to do this without .block() way if you want to return List<Products> from that method.

    You should rather merge the results and return Flux<Products> from this method to keep the reactive approach. You can use mergeWith or concatWith

    Example:

    public Flux<Products> getProducts(){
        List<Products> productsNonFlux = repositoryObj.getProductsNormal();
        Flux<Products> productsFlux = repositoryObj.getProductsFlux();
        return productsFlux.mergeWith(Flux.fromIterable(productsNonFlux));
    }
    

    IMPORTANT!

    Keep in mind that if your repositoryObj.getProductsNormal() is using JDBC then this call will block the thread pool.

    In such case take a look on: Execute blocking JDBC call in Spring Webflux