We don’t program for the sake of programming. It is obvious. At the end of this process, there is always a user of the product of our work. We can be proud of ourselves. We can praise our work, but it is the positive user experience that we want. And these we can expect only when the application, which he ordered from us, the operation of the main thread will be smooth. To make this happen, we have to perform many complicated operations in the background during our work, programming. To obtain the final effect expected by everyone, we need reactive programming – non-blocking and asynchronous.
Stream processing
Reactive Programming is a programming paradigm built around stream processing. Data is supported as a stream of data points passing through a pipeline of functions or operators. Before the data is passed to the next operator, each operator can transform and manipulate it. The operators can be a map, a collection, and other elements. These operations are chained until the transformed data is returned. Reactive programming, unlike imperative, does not maintain a state only changes it.
Non-blocking and asynchronous programming
Reactive programming is also non-blocking and asynchronous. Non-blocking code is another broad topic, but to simplify: it’s code, that 'doesn’t stop’ and 'doesn’t wait’ for something to finish (such as a disk read or a network call). Ideally, this allows for super high performance because the server can do all its work on a single thread. However, as in many cases, compromises become necessary.
Perfect code
For example, non-blocking code has historically been harder to implement, maintain, and debug (search the Internet for „callback hell”). To some extent, this has changed as technology has matured. However, the world is rarely perfect. Not all non-blocking code is non-blocking, and one piece of poorly written code in a dependency can start blocking an entire web service, ruining its performance. But if done right, reactive, non-blocking code can be a great tool. One use case where non-blocking, reactive code is great is stream handling.
What is Spring WebFlux?
Spring WebFlux is a reactive, non-blocking framework, for Spring Boot applications. It was created by Project Reactor for its reactive, non-blocking web server implementation and put on a Netty server. WebFlux supports other web server implementations such as Tomcat, Jetty, Undertow, and Servlet 3.1+ containers. Why would anyone use Tomcat or Jetty with Webflux (using a blocking servlet container with a reactive, asynchronous framework)? It’s an open question, but it’s nice to have this option too. It is worth mentioning that the application can use both Spring WebFlux and Spring Web MVC simultaneously.
What are the differences between a servlet stack and a reactive stack?
Servlet | Reactive |
Modułem aplikacji webowych Springa jest spring-webmvc | Moduł aplikacji webowych Springa to spring-webflux |
Spring MVC oparty na Servlet API | Spring WebFlux oparty o podstawę do wykorzystania wielordzeniowych procesorów nowej generacji |
Używa architektury synchronicznego blokowania I/O | Jest frameworkiem nieblokującym |
Jedno żądanie na wątek | Posiada zdolność do obsługi ogromnej ilości równoczesnych połączeń |
Domyślnie używa serwletów | Domyślnie używa Servlet 3.1+ i Netty |
Używa Repozytoriów Danych Spring jako JDBC, JPA, NoSQL | Używa reaktywnych repozytoriów danych Spring Data jako Mongo, Cassandra, Redis, Couchbase, R2DBC |
Model programowania wykorzystuje Servlet API | Model programowania wykorzystuje Adaptery strumieni reaktywnych |
Spring Security | Spring Security Reactive |
How does the database integration work?
NoSQL databases such as MongoDB, Redis, and Cassandra have native support for reactivity as part of Spring Data. Furthermore, many relational databases such as Microsoft SQL Server, MySQL, H2, Postgres, and Google Spanner have reactive support through R2DBC.
What is R2DBC?
R2DBC stands for Reactive Relational Database Connectivity. It offers integration of relational databases in a reactive application stack. So far, only NoSQL databases have native reactive support in Spring Data. R2DBC acts as an overlay to integrate relational databases using a reactive driver. Spring Data R2DBC applies popular Spring abstractions. It offers an easier way to build Spring-based applications that use relational databases such as Microsoft SQL Server, MySQL, Postgres, H2, etc., in a reactive application stack.
What is WebClient?
WebClient is a reactive web client for WebFlux base on the well-known RestTemplate. It is an interface that represents the main entry point for web requests and supports synchronous and asynchronous operations. WebClient is primarily used for reactive backend-to-backend communication.
Reactive Stream API
Reactive Stream API is an imported set of functions that enable smarter stream data flow. It has built-in support for back-pressure and asynchronous processing, which provides your application with the most efficient use of resources.
There are four primary interfaces in the Reactive Stream API:
- Publisher: emits events to connected subscribers based on their requirements. Functional as a central connection point that subscribers can observe events.
- Subscriber: receives and processes events emitted by publisher. Multiple subscribers can connect to a single publisher and react differently to the same event. Subscribers can be set to respond:
- onNext, when they receive the next event,
- onSubscribe, when a new subscriber is added,
- onError, when an error occurs with another subscriber.