React Router: A Comprehensive Tutorial...
February 22, 2024
Reactive programming is a programming paradigm that promotes an asynchronous, non-blocking, event driven approach to data processing. Reactive programming involves modelling data and events as observable data streams and implementing data processing routines to react to the changes in those streams.
In the reactive style of programming, we make a request for the resource and start performing other things. When the data is available, we get the notification along with the data in the form of call back function. In the callback function, we handle the response as per application /user needs.
Spring MVC: It’s based on a servlet API and follows an imperative programming model. This means you write code in a step-by-step manner, which is generally easier to follow.
Spring WebFlux: It offers a reactive programming model. Reactive programming is about handling asynchronous streams of data. This requires a change in thinking and can be more challenging than the traditional imperative model.
Spring MVC: If you are familiar with traditional web application development, Spring MVC’s imperative model might seem more straightforward. It’s easier to read, write, and understand for developers accustomed to this approach.
Spring WebFlux: Writing reactive code can initially seem complex because of the shift in mindset. However, for some use cases, like streaming data, it can simplify your code.
Spring MVC: Debugging is typically more straightforward with an imperative model because the call stacks are more predictable and easier to trace.
Spring WebFlux: Debugging reactive streams can be tricky, especially for developers new to the reactive paradigm. However, tools and practices are evolving to better support this.
Spring MVC: Works naturally with blocking resources like traditional RDBMS using JDBC or JPA (Java Persistence API).
Spring WebFlux: If you have blocking dependencies like traditional databases, you might not get the full benefits of the reactive model. However, reactive databases like MongoDB Reactive, Cassandra Reactive, etc., can be integrated natively with WebFlux.
Spring MVC: Uses a thread-per-request model. For a high number of simultaneous connections, this can lead to a large number of threads, which may not be efficient.
Spring WebFlux: Uses an event-loop concurrency model, which can handle a vast number of simultaneous connections with a smaller number of threads. It’s designed for high concurrency.
Spring MVC: Typically runs on servlet containers like Tomcat, Jetty, etc.
Spring WebFlux: Runs on reactive runtimes like Netty. This provides non-blocking and highly scalable operations, suitable for high-performance systems.
Spring MVC: Typically uses annotated controllers.
Spring WebFlux: In addition to annotated controllers, WebFlux supports functional endpoints which allow for programmatic route definitions.
As we know, Spring provides Web MVC framework to handle the HTTP requests, but it is Blocking & Non-Reactive in nature, so to support reactive programming Spring provides one more web framework in Spring 5 (includes in Spring Boot 2.0) called WebFlux.
It is a reactive-stack web framework that is fully non-blocking, supports reactive streams back pressure. It uses project Reactor as a reactive library. The Reactor is a Reactive Streams Library and therefore, all of its operators support non-blocking back pressure.
It uses two publishers:
A mono is a specialized Publisher that emits at most one item and then optionally terminates with an onComplete signal or an onError signal. In short, it returns 0 or 1 element.
Mono noData = Mono.empty();
Mono data = Mono.just(“rishi”);
A flux is a standard Publisher representing an asynchronous sequence of 0 to N emitted items, optionally terminated by either a completion signal or an error. These three types of signals translate to calls to a downstream subscriber’s onNext, onComplete, or onError methods.
To subscribe, we need to call the subscribe method on Flux. There are different variants of the subscribe method available, which we need to use as per the need:
Flux flux1 = Flux.just(“foo”, “bar”, “foobar”);
Flux flux2 = Flux.fromIterable(Arrays.asList(“A”, “B”, “C”));
Flux flux3 = Flux.range(5, 3);
Frequently used operations on Mono/Flux
Requirement: Send Promos to all the customers of an e-Commerce website
Step-1: Create a Spring Boot project using Maven (Choose Spring Boot version 2.0 or later)
Step-2: Add the below spring-boot-starter-webflux dependency in pom.xml
This dependency includes the below dependencies
reactor-netty (the default server that supports reactive streams). Any other servlet 3.1+ containers like Tomcat, Jetty or non-servlet containers like Undertow can be used as well
Version will be picked from spring-boot-starter-parent dependency version
Step-3: Create a Customer DTO class with the fields Id, Name & Email Id
Step-4: Create a Customer Repo with 2 functions loadCustomers(), loadCustomerStream() as in the below snapshot.
Step-5: Create a Customer Service with 2 functions, one is to send promos to list of customers, another is to send promos to customer stream
Step-6: Create a Customer REST Controller with 2 end points as in the below screenshot
Step-7: Start the Spring Boot Web Flux Application
Step-1: Take the same(above) Spring Boot project
Step-2: Add a function in CustomerDao to find Customer by email Id, return Error Mono if the Customer is not found with the email Id else return the Customer Mono as in below screenshot
Step-3: Define one Response wrapper class with the fields path, timestamp, status code, error, warning, success, data fields
Step-4: Autowire CustomerDao in CustomerController class & add one more end point in class to find the Customer by email Id, handle the error Mono in the Controller itself as in the below screenshot
Spring introduced a Multi-Event Loop model to enable a reactive stack known as WebFlux. It is a fully non-blocking and annotation-based web framework built on Project Reactor which allows building reactive web applications on the HTTP layer. It provides support for popular inbuilt severs like Netty, Undertow, and Servlet 3.1 containers.
Spring WebFlux or Reactive non-blocking applications usually do not make the applications run faster. The essential benefit it serves is the ability to scale an application with a small, fixed number of threads and lesser memory requirements while at the same time making the best use of the available processing power. It often makes a service more resilient under load as they can scale predictably.
WebFlux is also relevant for applications that need scalability or to stream request data in real time. While implementing a micro-service in WebFlux we must consider that the entire flow uses reactive and asynchronous programming and none of the operations are blocking in nature.
Git URL for a basic demo of Spring Reactive Programming: https://github.com/YashKakrechaInexture/flux-demo