It's time to look at a very interesting and exciting programming paradigm. In this section, you will learn about Reactive Programming. What is it? Why does anyone need to learn it? What are the advantages that it offers? Time to find out!
What is Reactive Programming?
Reactive programming is a programming paradigm oriented around data flows, and the propagation of change. This means that it should be possible to express static or dynamic data flows with ease in the programming languages used, and that the underlying execution model will automatically propagate changes through the data flow. - Wikipedia
Sounds complicated? Simply put, reactive programming promotes non-blocking, asynchronous, event-based data processing. Let's shine a light on this to help clear things up.
The Need for the Reactive Paradigm
As you may already know, the traditional servlet architecture is blocking and synchronous. But what does this mean? Basically, this means that the thread responsible for handling a request will "block" any further execution until a response is received. It is a one-request-per-thread model.
Consider these two types of communication:
-
Synchronous — The client submits a request and then "blocks", waiting for the result before continuing execution.
-
Asynchronous — The client submits a request and then goes back to business as usual. It processes the result later when it is made available.
Handling Asynchronous Requests
How does reactive programming handle asynchronous requests? In reactive programming, asynchronous requests are handled via non-blocking operations. Think about this. Take the threads responsible for requests - instead of waiting on a response, they are set free to complete other tasks. When the result is ready, the client is notified and any free thread can then process the response. What this (very loosely) describes is an Event Loop.
This is one model used in reactive programming to promote asynchronous communication. Its goal is to ensure that no thread is ever in a waiting (blocking) state. This leads to more efficient processing, more concurrent requests, and a great user experience overall. In a way you can think of reactive programming as a publisher-subscriber architecture based around events.
While an event loop is common in some reactive programming frameworks, reactive programming encompasses more than just event loops. It involves a full-fledged approach to data processing that includes stream-based processing, backpressure handling, and a publisher-subscriber model to efficiently manage data flow and event handling without blocking threads.
Where is Reactive Programming Used?
Reactive programming is particularly well-suited for scenarios involving asynchronous data streams, high concurrency, and where system scalability and responsiveness are critical.
-
Real-Time Data Processing: Reactive programming is ideal for applications that require real-time processing of data streams, like financial trading platforms monitoring systems, and IoT applications. In these scenarios, data is continuously generated and needs to be processed and reacted to as it arrives.
-
Web Applications with High Traffic: Web applications with exceptionally high traffic can benefit significantly from reactive programming. E-commerce platforms, social media applications, and online gaming platforms are great examples.
Think of how much data processing Facebook needs to do to render each user's page. If these requests were to be synchronous, would Facebook be able to serve such a large number of users effectively?
Reactive programming enables these applications to handle a huge number of concurrent client connections with fewer threads, reducing overhead and improving response times. This is especially important for services with unpredictable or highly variable load patterns.
-
Microservices Communication: In a microservices architecture, different services need to communicate with each other. Reactive programming can enhance the overall system's resilience and efficiency by allowing for non-blocking communication and backpressure, a mechanism that prevents overwhelming a service with more requests than it can handle.
-
Spreadsheets: By this time, it's certain that you have used some form of spreadsheet, be it Excel, Google Sheets, or Apple Numbers. Visualizing the use case of reactive programming in a spreadsheet might not be super obvious. Imagine a cell X depends on a cell Y, and then cell Z depends on both cells X and Y. So if the value of cell Y changes, how will you ensure that X is updated before any change occurs in cell Z? Yes, you guessed it right: reactive programming. The change in cell Y triggers an event that is first subscribed by cell X which in turn triggers another event to be subscribed by cell Z.
Each of these use cases demonstrates the strength of reactive programming in handling asynchronous operations, managing data streams, and maintaining system responsiveness under high loads or in distributed environments. By enabling non-blocking operations and providing mechanisms for dealing with latency and backpressure, reactive programming helps build scalable, responsive, and resilient applications.
Reactive programming is gaining popularity, especially at the enterprise level. It is an approach that all programmers should be familiar with.
Reactive Programming in Java + Spring
Project Reactor is a reactive library for building non-blocking applications on the JVM, based on the Reactive Streams Specification. It's the foundation of the reactive stack in the Spring ecosystem and is featured in projects such as Spring WebFlux and Spring Data. You'll learn more about how to utilize these in the sections ahead.
Is Reactive Programming Right For Your Project?
Hold On! After this introduction to reactive programming, you're probably screaming "sign me up!". But like most development decisions, it's not quite that cut and dry.
Reactive and functional programming change how you work in many ways. But don't go running off and immediately convert all of your projects to this paradigm without careful consideration.
First off, non-reactive stacks work just fine for most projects, and RestTemplate isn't going anywhere any time soon. Second, annotated controllers are functionally equivalent to functional endpoints in most regards, and their use should be based on user preference & project requirements.
There are tons of existing and future applications that have been or will be written with the Spring servlet stack. While some applications can/will benefit from the reactive stack, many will not. All of this will make more sense in the upcoming lessons.
Summary: Reactive Programming
- Reactive programming is oriented around data flows and change propagation.
- Synchronous communication — threads trigger execution and wait for a result.
- Asynchronous communication — threads trigger execution and are then freed for utilization by other tasks, the result is processed later when it's made available.
- While Reactive programming is helpful in several use cases, it isn't absolutely necessary to utilize in the majority of projects. This section aims to teach you advanced skills for when they may come in handy.