spring-webfluxspring-reactive

Spring data - webflux - Chaining requests


i use reactive Mongo Drivers and Web Flux dependancies

I have a code like below.

  public Mono<Employee> editEmployee(EmployeeEditRequest employeeEditRequest) {
        return employeeRepository.findById(employeeEditRequest.getId())
                .map(employee -> {
                    BeanUtils.copyProperties(employeeEditRequest, employee);
                    return employeeRepository.save(employee) 
                })
    }

Employee Repository has the following code

Mono<Employee> findById(String employeeId)
  1. Does the thread actually block when findById is called? I understand the portion within map actually blocks the thread.

  2. if it blocks, how can I make this code completely reactive?

  3. Also, in this reactive paradigm of writing code, how do I handle that given employee is not found?


Solution

  • Yes, map is a blocking and synchronous operation for which time taken is always going to be deterministic.

    Map should be used when you want to do the transformation of an object /data in fixed time. The operations which are done synchronously. eg your BeanUtils copy properties operation.

    FlatMap should be used for non-blocking operations, or in short anything which returns back Mono,Flux.

    "how do I handle that given employee is not found?" - findById returns empty mono when not found. So we can use switchIfEmpty here.

    Now let's come to what changes you can make to your code:

      public Mono<Employee> editEmployee(EmployeeEditRequest employeeEditRequest) {
        
        return employeeRepository.findById(employeeEditRequest.getId())
            .switchIfEmpty(Mono.defer(() -> {
              //do something
            }))
            .map(employee -> {
              BeanUtils.copyProperties(employeeEditRequest, employee);
              return employee;
            })
            .flatMap(employee -> employeeRepository.save(employee));
    
      }