Hexy
Hexy

Reputation: 857

Should we use Mono<T> for non IO Operations?

Is there any benefit/drawback in using Mono vs just ReturnType in a Reactive Java App.

If you are just doing data validation does it make sense to use a Mono

For ex: Option 1

public Mono<String> createEmployee(String name, String dept, String age){
    Employee e;

try {
    e = new Employee(name, dept, age);
  } catch ( ValidationException ve){
    logger.error("Invalid inputs: ", ve);
    return Mono.error(ve);
 }
 return DBUtils.createEmployee(e).flatMap(
    e -> {
     return Mono.just(e.getId());
   }
  );
}

Option 2

public Mono<String> createEmployee(String name, String dept, String age){
   return Mono.just(new Employee(name, dept, age))
              .flatMap(e -> DBUtils.createEmployee(e))
              .flatMap(e -> Mono.just(e.getId())
              .onErrorResume(e -> Mono.just("Invalid Inputs"));
  }

Is there a rule like if there is no IO operation don't use Mono?

Upvotes: 0

Views: 485

Answers (1)

Michael Berry
Michael Berry

Reputation: 72294

If you are just doing data validation does it make sense to use a Mono

No, unless that validation could somehow involve a blocking operation (like sending the data to a server to be validated), in which case it would make sense. Here though it just looks like you're processing some logic in a standard method with no blocking operations like API calls at play.

However, in your example you are doing something more than validation - it looks like you're actually saving an employee to a database (I assume that's what DBUtils.createEmployee(e) does) - and in that case it makes complete sense to use a Mono, as that's a textbook use case (allowing you to take a traditionally blocking operation and instead making it part of a reactive chain.)

So assuming the above is true, then option 2 does make sense - but it could certainly be simplified based on two particular guidelines:

  • There's no point using flatMap() unless your operation actually returns a publisher - otherwise just use map() instead;
  • There's no point creating a POJO, wrapping it in a Mono then mapping it - just start with the publisher as the first element in the chain instead.

So instead of your option 2, it'd be better to use something like:

return DBUtils.createEmployee(new Employee(name, dept, age))
          .map(Employee::getId)
          .onErrorResume(e -> Mono.just("Invalid Inputs"));

Upvotes: 2

Related Questions