Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Processing Optional Value from Mono in Project Reactor

I want to have a Mono that calls another async method that returns an Optional type to:

  1. have a value if the Optional is not empty,
  2. is MonoEmpty if the Optional value is empty.

Here's what I do right now:

Mono.fromCallable(() -> someApi.asyncCall()) .filter(Optional::isPresent) .map(Optional::get)

Obviously, this is not ideal since it uses two operators after the callable completed. If possible, I'd like to have the Mono.empty() or mono value from inside fromCallable.

What is the best way to achieve what I want?

like image 386
bertzzie Avatar asked Nov 07 '18 08:11

bertzzie


People also ask

How do you extract values from a mono object?

Blocking way to get value from Mono WebFlux. You can use the block() method to block the current thread indefinitely and wait for Mono to complete. If the Mono completes, then this method either returns the original value or null (Mono is empty). In case of any errors, then the exception is rethrown.

How do you handle empty mono?

Default value if mono is empty. If you want to provide a default value when the mono is completed without any data, then use defaultIfEmpty method. For example, the following code tries to fetch the customer data from the database by using the customer id .

What is the difference between flux and Mono?

A Flux object represents a reactive sequence of 0.. N items, while a Mono object represents a single-value-or-empty (0..1) result. This distinction carries a bit of semantic information into the type, indicating the rough cardinality of the asynchronous processing.

How do you make flux with mono?

First, we'll extract collection items from stream publisher Mono and then produce items one by one asynchronously as Flux. The Mono publisher contains a map operator, which can transform a Mono synchronously, and a flatMap operator for transforming a Mono asynchronously.


3 Answers

There is an alternative with flatMap that's a bit better than Optional.isPresent and Optional.get that can lead to accidentally calling get on empty Optional:

Mono.fromCallable(() -> someApi.asyncCall())
  .flatMap(optional -> optional.map(Mono::just).orElseGet(Mono::empty))
like image 70
Ilya Zinkovich Avatar answered Nov 09 '22 00:11

Ilya Zinkovich


Mono have justOrEmpty method that you can use with Optional<? extends T> type. When Optional.empty() == true we would have MonoEmpty.

Create a new Mono that emits the specified item if Optional.isPresent() otherwise only emits onComplete.

Mono<String> value = Mono.justOrEmpty(someApi.asyncCall());
like image 33
slisnychyi Avatar answered Nov 08 '22 22:11

slisnychyi


How about:

Optional<Integer> optional = Optional.of(5);
Mono<Optional<Integer>> monoWithOptional = Mono.just(optional);
Mono<Integer> monoWithoutOptional = monoWithOptional.flatMap(Mono::justOrEmpty);
like image 26
Roger Gouveia Avatar answered Nov 09 '22 00:11

Roger Gouveia