The image was generated using https://gemini.google.com/

The core components of Spring Reactive primarily include the following building blocks —

Mono

Mono is a Reactive Stream Publisher which can emits maximum 1 element via onNext signal or only emits a single onError signal.

Flux

Flux is also a Reactive Stream Publisher similar to Mono but it can emits multiple elements via onNext signal and then completes with either success or error signal.

Mono

As previously mentioned Mono can emit maximum 1 element. It can be used when we know the underlaying publisher will publish maximum 1 element or an error signal.

How can we create a new Mono

Mono can be created in multiple ways, here are the couple of ways to do the same —

  • Mono.empty() — When you just want to create empty Mono publisher, Mono.empty() can be used.
  • Mono.just(<element>) — When you already know the element, an instance of Mono can be easily created by using Mono.just(<element>). For example
Mono.just(5); // Will create a Mono which emit 5 as next element
  • Mono.justOrEmpty() — When you have a nullable value, Mono.justOrEmpty() can be used to create a Mono. Based on input it’ll either provide a empty Mono similar to Mono.empty() or Mono with 1 element similar to Mono.just(<element>). You can also provide Optional value as an input to Mono.justOrEmpty(<Optional>). For example
Mono.justOrEmpty(5); // Will create a Mono which emit 5 as next element
Mono.justOrEmpty(Optional.of(5)); // Will create a Mono which emit 5 as next element

Mono.justOrEmpty(null); // Will create a empty Mono
Mono.justOrEmpty(Optional.empty()); // Will create a empty Mono
  • Mono.fromCallable(<runnable>) — When the element is not directly available and need to invoke some sort of synchronous/blocking method to produce the value Mono.fromCallable(<runnable>) can be used. Incase provided Runnable returns null value, then it’ll create an empty Mono. For example
Mono.fromCallable(() -> 5); // Will create a Mono which emit 5 as next element
Mono.fromCallable(() -> null); // Will create a empty Mono
Mono.fromCallable(() ->
new RuntimeException("Just a demo error scenario")); // will create a Mono which emits error signal
  • Mono.defer(<supplier>) — This method is also similar to Mono.fromCallable(<runnable>) but in this case the provided supplier already returns a Mono. This is particularly useful to create a completely new Mono stream from one of the existing stream. For example
Mono.defer(() -> Mono.just(5)); // Will create a Mono which emit 5 as next element
  • Mono.error(<throwable/throwable supplier>) — When there is a need to create Mono which emits error signal instead of a success Mono.error(<throwable/throwable supplier>) can be used. For example
Mono.error(new RuntimeException("Just a demo error scenario"));
Mono.error(() -> new RuntimeException("Just a demo error scenario"));

There are many other ways of creating a Mono, but here I just added most of common ways to create a new Mono, more information can be found on Spring documentation.

Flux

Flux is used as publisher to emit 0 to N elements. Flux may produce multiple error signal based on our use-case (we’ll discuss this in later part) but generally it stops when the first error signal emits.

How can we create a new Flux

Flux can be created in multiple ways, here are couple of ways to do the same —

  • Flux.empty() — When you just want to create empty Flux publisher, Flux.empty() can be used.
  • Flux.just(<elements>) — When you already know the elements, an instance of Mono can be easily created by using Flux.just(<elements>). For example
Flux.just(5); // Will create a Flux which emit 5 as next element
Flux.just(5, 9, 0, 6, 4); // Will a Flux which will emits the elements in order as 5, 9, 0, 6 and 4
  • Flux.fromIterable(<iterable>) — When the elements are already part of some sort of Iterable like, List, Set etc, Flux.fromIterable(<iterable>) can be used to convert Iterable to a Flux publisher. For example
Flux.fromIterable(List.of(1, 2, 3));
Flux.fromIterable(Set.of(1, 2, 3));
  • Flux.fromStream(<stream/stream supplier>) — When the elements are part of Stream or the elements will be provided as Stream once some method is invoked, then Flux.fromStream(<stream/stream supplier>) can be used to create a Flux publisher from the Stream. For example
Flux.fromStream(Stream.of(1, 2, 3));
Flux.fromStream(() -> Stream.of(1, 2, 3));
  • Flux.defer(<supplier>) — When there is a need to create a new Flux from an existing one, we can use Flux.defer(<supplier>). For example
Flux.defer(() -> Flux.just(1, 2, 3));
  • Flux.error(<throwable/throwable supplier>) — When there is a need to create Flux which emits error signal instead of a success Flux.error(<throwable/throwable supplier>) can be used. For example
Flux.error(new RuntimeException("Just a sample error scenario"));
Flux.error(() -> new RuntimeException("Just a sample error scenario"));

There are many other ways of creating a Flux, but here I just added most of common ways to create a new Flux, more information can be found on Spring documentation.

Conclusion

In summary, Mono and Flux stand as pivotal elements within Spring Reactive, providing robust abstractions for managing asynchronous data streams. Mono handles single or optional results, while Flux caters to streams with 0 to N items. Mastery of these components equips developers to create responsive, resilient, and scalable applications, maximising the capabilities of Spring Reactive.

This article is a segment of the Cooking up Reactivity: The Spring Way series. To explore the entire series, click here.

Originally posted on medium.com.