Creating Efficient Reactive Systems with Java

An Introduction to Project Reactor

Silas Candiolli
abbeal’s tech blog
3 min readJul 7, 2023

--

Project Reactor is a powerful open-source library for building reactive applications in Java. It provides an extensive set of tools and abstractions that enable developers to write asynchronous, event-driven, and non-blocking code.

Reactor is based on the Reactive Streams specification, which defines a standard for building reactive systems. It embraces the reactive programming paradigm, where applications are designed to react to incoming events and efficiently handle concurrent and asynchronous operations.

At its core, Reactor introduces two fundamental data types: Flux and Mono. Flux represents a stream of zero to N elements, while Mono represents a stream that emits either zero or one element. These types provide a rich set of operators to perform various transformations and operations on data streams, such as mapping, filtering, and combining.

Features

One of the key features of Reactor is its support for backpressure. Backpressure is a mechanism that allows consumers to control the rate at which data is produced by publishers. Reactor provides strategies and operators to handle backpressure, ensuring that data flows smoothly through the system, preventing overload or resource exhaustion.

Error handling and resilience are also essential aspects of Reactor. The library provides operators to handle errors, such as retrying operations or falling back to alternative sources. It also integrates well with existing error-handling mechanisms in Java, making it easy to handle exceptions in reactive applications.

Benefits

With Reactor, developers can write scalable and efficient applications that are responsive and resilient to failures. Its functional and declarative programming style promotes code readability and maintainability, making it easier to reason about complex asynchronous workflows.

Project Reactor has gained significant popularity in the Java ecosystem and is widely used in various domains, including microservices, data streaming, and web development. It continues to evolve with regular updates, enhancements, and new features, staying at the forefront of reactive programming in Java.

Whether you’re building small-scale applications or large-scale distributed systems, Reactor empowers you to harness the power of reactive programming and unlock the benefits of asynchronous, event-driven development in Java.

Hello Word

To have a better understanding, the following code introduces you to how to create your first Mono and Flux.

@Test
public void hello_world_mono() {
// Create a Mono from String, but it could be a call to another function or reactive web service
Mono<String> serviceResult = Mono.just("Hello World!");

// Use the block method to stop de flow and get results from serviceResult
String result = serviceResult.block();

assertEquals("Hello World!", result);
}

@Test
public void hello_world_flux() {
// Create a Flux from String, but it could be a call to another function or reactive web service
Flux<String> serviceResult = Flux.just("Hello World 1", "Hello World 2");

// Use the block method to stop de flow and get results from serviceResult
List<String> result = serviceResult.collectList().block();

for (int i = 1; i < 3; i++) {
assertEquals("Hello World "+i, result.get(i-1));
}
}

Look at how I’m using the block method to get results from Mono and Flux. That is a very simple example, if you are working on a real project you will use the StepVerifier to test. StepVerifier is an interface that provides a declarative way to test async Publisher’s sequence, by expressing expectations.
Let's see how it works:

@Test
public void hello_world_mono() {
// Create a Mono from String, but it could be a call to another function or reactive web service
Mono<String> serviceResult = Mono.just("Hello World!");

StepVerifier
.create(serviceResult)
.expectNext("Hello World!")
.expectComplete()
.verify();
}

@Test
public void hello_world_flux() {
// Create a Flux from String, but it could be a call to another function or reactive web service
Flux<String> serviceResult = Flux.just("Hello World 1", "Hello World 2");

StepVerifier
.create(serviceResult)
.expectNext("Hello World 1")
.expectNext("Hello World 2")
.expectComplete()
.verify();
}

This way, you will subscribe to the Mono and Flux to verify the results when they arrive.

I hope this post helps you to know the Project Reactor and get started with reactive programming in Java. Enjoy!

Over the next 10 weeks, I’ll be sharing content about Project Reactor. If you are interested, follow me there: repository and blog

--

--