Spring WebFlux Mono vs Flux

Okay, let’s break down the difference between Flux and Mono in Spring WebFlux, which is Spring Boot’s reactive programming module.

Fundamentally

  • Mono: Represents zero or one element. Think of it as a single, potentially asynchronous result.
  • Flux: Represents zero to many elements (a stream of data). It’s like a sequence or a collection of results, possibly arriving over time.

Analogy

Imagine a restaurant:

  • Mono: Getting the recipe for a single dish. Either you get the recipe (one element), or the chef hasn’t written it down yet (zero elements – completion without a value).
  • Flux: Getting all the dishes served throughout the entire day. The chef prepares a series of dishes, each appearing in the stream as they’re made. The stream finishes when the restaurant closes (completion).

Key Differences in Detail

Feature Mono Flux
Representation Single value or no value Sequence (stream) of values
Use Cases – Asynchronous operation returning one result – Handling streams of data
– Retrieving a single user from a database – Real-time updates (e.g., stock prices)
– Completing an action (e.g., saving to DB) – Processing large datasets in chunks
Completion Completes successfully with or without a value. Completes successfully when the stream ends.
Error Handling Emits an error signal, terminates the sequence. Emits an error signal, terminates the sequence.
Typical Operators map, flatMap, filter, zip (for combining with other Mono instances) map, flatMap, filter, scan, buffer, window, concat
Return Type of Spring WebFlux Methods Many controller methods for single entity retrieval, updates, deletions. Also, service layer methods that return a single result. Many controller methods for returning a list of entities, server-sent events, websocket streams. Also, service layer methods that process data in chunks or streams.

Code Examples (Simplified)

import reactor.core.publisher.Mono;
import reactor.core.publisher.Flux;

public class Example {

    public static void main(String[] args) {

        // Mono: Emits a single string "Hello"
        Mono<String> singleValue = Mono.just("Hello");

        singleValue.subscribe(
                System.out::println,  // onNext: Prints the value
                System.err::println,   // onError: Prints the error
                () -> System.out.println("Mono completed") // onComplete:  Signals completion
        );


        // Flux: Emits a sequence of integers 1, 2, 3
        Flux<Integer> multipleValues = Flux.just(1, 2, 3);

        multipleValues.subscribe(
                System.out::println,  // onNext: Prints each value
                System.err::println,   // onError: Prints the error
                () -> System.out.println("Flux completed")  // onComplete: Signals completion
        );


        // Mono: Empty Mono (no value)
        Mono<String> emptyMono = Mono.empty();
        emptyMono.subscribe(
                System.out::println,
                System.err::println,
                () -> System.out.println("Empty Mono completed")
        );


        // Flux:  Flux from a range of numbers
        Flux<Integer> rangeFlux = Flux.range(5, 3); // Emits 5, 6, 7

        rangeFlux.subscribe(
                System.out::println,
                System.err::println,
                () -> System.out.println("Range Flux completed")
        );
    }
}

Spring WebFlux Context

In Spring WebFlux, you’ll often see:

  • Controllers:
    • Use Mono to return a single entity (e.g., @GetMapping("/users/{id}") might return Mono<User>).
    • Use Flux to return a list of entities, stream data, or implement Server-Sent Events (SSE) or WebSockets.
  • Services:
    • Use Mono for operations that return a single result (e.g., saving a user to the database, retrieving a user by ID).
    • Use Flux for operations that process data in chunks, streams, or retrieve multiple results (e.g., querying a database for all users, processing a file line by line).
  • Repositories (with Reactive Data Repositories):
    • Return Mono for findById(), save(), deleteById().
    • Return Flux for findAll(), findBy...().

When to Use Which

  • Use Mono when: You’re dealing with a single, potentially asynchronous result (a user, a configuration setting, the success or failure of an operation).
  • Use Flux when: You’re working with a stream of data (real-time updates, a list of items, processing a file).

Important Considerations

  • Reactive Programming: Mono and Flux are part of the reactive programming model. They enable non-blocking operations and efficient resource utilization, especially important for high-concurrency applications.
  • Backpressure: Flux supports backpressure, allowing the consumer of the stream to signal to the producer how much data it can handle. This prevents the consumer from being overwhelmed. Mono doesn’t need backpressure handling as it emits at most one element.
  • Transformation: You can transform Mono and Flux using a rich set of operators (e.g., map, flatMap, filter, zip). These operators allow you to process and manipulate the data in the reactive stream.

In summary, the choice between Mono and Flux depends entirely on whether you’re working with a single value or a stream of values. They’re fundamental building blocks for reactive applications in Spring WebFlux.

Leave a Comment

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.

Scroll to Top