Mono
Reactor
switchIfEmpty
Java
Reactive Programming

Mono switchIfEmpty is always called

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In the reactive programming world, dealing with nulls or empty states is crucial to building robust and non-blocking applications. When using Project Reactor's Mono class, a reactive type that either emits zero or one item, there is an elegant method to handle empty emissions: switchIfEmpty(). This method is crucial for managing fallback logic in reactive streams when no data is emitted.

What is Mono.switchIfEmpty()?

switchIfEmpty() is an operator that provides an alternative Mono when the original Mono emits an empty signal. It’s essential in scenarios where you anticipate a possibility of no data being emitted and need to define a fallback logic or an alternative pathway.

Usage

The Mono.switchIfEmpty() method allows you to switch the stream to another Mono. It can be particularly useful when fetching data from a source that may not always return a value, such as an empty database query.

Syntax

java
Mono<T>.switchIfEmpty(fallback: Mono<? extends T>)
  • Fallback Mono: A Mono to subscribe to when the original Mono completes empty.

Technical Explanation

Let's break down how switchIfEmpty() works with an example:

Example: Retrieving Data with Fallback

Suppose you want to fetch a user’s profile from a database. If the user isn’t found (empty result), you want to load a default profile.

java
1Mono<User> findUserById(String userId) {
2    return userRepository.findById(userId);
3}
4
5Mono<User> getDefaultUser() {
6    return Mono.just(new User("default", "guest"));
7}
8
9Mono<User> userProfile = findUserById("12345")
10    .switchIfEmpty(getDefaultUser());

In this example:

  • findUserById("12345") may return an empty Mono if the user is not found.
  • The switchIfEmpty() operator will switch to getDefaultUser() only if findUserById() completes without emitting any item.

Reactive Streams and Empty Mono

From a Reactive Streams perspective, Mono.switchIfEmpty() adds another layer for handling the completion signals. A typical Mono without items delivers an onComplete signal without onNext. When switchIfEmpty() is applied, it allows a secondary Mono to potentially emit a value upon the completion of the first empty Mono.

Sequence Flow:

  1. Subscribe: A subscriber subscribes to the Mono.
  2. Emit or Complete: The Mono either emits an item or completes without emission.
  3. Fallback Activation: If the Mono completes empty, switchIfEmpty() activates the fallback Mono.

Practical Applications

Use Case: Caching

In applications that implement caching, switchIfEmpty() can be used to serve as a mechanism to fetch data either from the cache or fallback to a database or another service:

java
1Mono<Product> getProduct(String productId) {
2    return cache.getProduct(productId)
3               .switchIfEmpty(database.getProduct(productId));
4}
  • Cache Hit: If the product is in the cache, it is returned.
  • Cache Miss: If not, switchIfEmpty() causes the system to fetch from the database.

Use Case: Authentication

In scenarios where user authentication could either be handled in-memory or fallback to a service call:

java
1Mono<User> authenticate(UserCreds creds) {
2    return inMemoryAuth(creds)
3                .switchIfEmpty(remoteAuthService.authenticate(creds));
4}
  • Local Authentication: Attempts to authenticate locally.
  • Fallback: If local auth fails (empty), falls back to a remote authentication service.

Key Points

AspectDescription
Primary FunctionProvides an alternative Mono if the original is empty.
Fallback ScenarioExecutes fallback logic when no data is emitted.
Common Use CasesData retrieval, caching mechanisms, authentication fallbacks.
Reactive SequenceInvolves subscribe, emit or complete, and fallback activation.
Coding PatternMono<T>.switchIfEmpty(fallback: Mono<? extends T>)

Conclusion

Mono.switchIfEmpty() is a powerful method that enables developers to define alternative logic for empty mono emissions gracefully. By using this pattern, you can ensure that applications remain resilient and responsive even when data sources do not yield any result. With its typical integration in caching, fallback data retrieval, or authentication systems, switchIfEmpty() remains an essential tool in the reactive programming toolkit.


Course illustration
Course illustration

All Rights Reserved.