Reactive Programming
Reactive Programming
Data is processed in bulk and can’t be handed over to the next task until the
previous task has completed its work on the bulk of data.
Reactive code
A set of tasks is defined to process data, but those tasks can run in parallel.
Each task can process subsets of the data, handing it off to the next task in line
while it continues to work on another subset of the data.
Reactive Programming
Reactive programming is functional and declarative in nature.
Rather than describe a set of steps that are to be performed
sequentially, reactive programming involves describing a pipeline or
stream through which data flows.
Rather than requiring the data be available to be processed as a
whole, a reactive stream processes data as it becomes available.
Reactive Streams aims to provide a standard for asynchronous
stream processing with non-blocking backpressure.
Java Stream vs Reactive Streams
Java Streams:-
synchronous and work with a finite set of data
Reactive Streams
asynchronous processing of datasets of any size, including
infinite datasets.
process data in real time, as it becomes available, with
backpressure to avoid overwhelming their consumers.
Data Flow in Reactive Stream
Publisher
Subscriber
Back Pressure on Data Streams
Problems:
Client application may not be able to handle huge data.
Client application may crash with out of memory error.
Reactive Program apply backpressure by which the client can request the amount of data it
can handle and the server limit the data depending on the client request
Building Blocks of Reactive Programming
Publisher
A Publisher produces data that it sends to a Subscriber per a
Subscription.
Subscriber
Consume the data from publisher through Subscription object.
Subscription
It represents the subscription details of a subscriber with the
publisher.
Processor
A Processor represents a processing stage contains both Publisher
and Subscriber.
Reactive Streams specification
Publisher
Publisher is a data source which can always publish an event.
The Subscriber can call request() to request that data be sent, or it can call cancel() to indicate that
it’s no longer interested in receiving data and is canceling the subscription.
Processor
A Processor represents a processing stage – which is
both a Subscriber and a Publisher and MUST obey the
contracts of both.
The Processor interface, it’s a combination of Subscriber
and Publisher
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
Reactor Data Types
In order for an application to be reactive, the first thing it must be able to
do is to produce a stream of data.
Reactive Core gives us two data types that enable us to do this.
Flux
It's a stream that can emit 0 to N number of data items.
Eg:
Flux<Integer> just = Flux.just(1, 2, 3, 4);
Mono
It is a stream of 0 or 1 data items.
Eg:-
Mono<Integer> just = Mono.just(1);
Create Reactive Types
When working with reactive types in Spring, you’ll be given a
Flux or a Mono from a repository or a service, so you won’t
need to create one yourself.
But occasionally you’ll need to create a new reactive
publisher.
Reactor provides several operations for creating Fluxes and
Monos.
Create Project
Add Spring Reactive Web
as dependency
Add a New Java Class
Create Mono - Example
import reactor.core.publisher.Mono;
@SpringBootApplication
public class ReactiveExampleApplication {
public static void main(String[] args) {
//call testMono()
new MonoFluxDemo().testMono();
SpringApplication.run(ReactiveExampleApplication.class, args);
}
}
Test Mono Example
Create Flux – Example
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
}
Test Flux
Log Info for Flux elements
public class MonoFluxDemo {
public void testFlux() {
Flux<String> fluxdata = Flux.just("Apple","Orange", "Manago","Pineapple","Grapes")
.log();
fluxdata.subscribe(System.out :: println);
}
}
Flux operations
Flux also provides the option to create more complex
functional operations such as filter, map etc..
public class MonoFluxDemo {
public void testFlux() {
Flux<Double> fluxdata = Flux.just(1,10,67,23,22,89,100,50,65,24)
.filter(item -> item%2 == 0)
.map(item->Math.pow(item, 2));
fluxdata.subscribe(System.out :: println);
}
Filter only even and make square of it
}
Combining Reactive Types
mergeWith() method used to combine two flux data
import reactor.core.publisher.Flux;
public class MonoFluxDemo {
public void testFlux() {
Flux<Integer> fluxdata1 = Flux.just(1,2,3,4,5);
Flux<Integer> fluxdata2 = Flux.just(10,20,30,40,50);
}
Transforming and filtering reactive streams
map()
creates a Flux that simply performs a transformation as
prescribed by a given Function on each object it receives before
republishing it.
flatMap()
to perform the mapping asynchronously, you should consider the
flatMap() operation.
map() transformation example
}
Developing Reactive APIs
Traditional Web MVC Framework
Spring MVC, are blocking and multithreaded in nature, using
a single thread per connection.
The request thread is blocked until it’s notified by the worker thread
that it’s finished.
Consequently, blocking web frameworks won’t scale effectively
under heavy request volume.
Latency in slow worker threads makes things even worse because
it’ll take longer for the worker thread to be returned to the pool,
ready to handle another request.
With an increasing number of clients consuming web applications,
scalability is more important than ever.
Asynchronous web frameworks
Achieve higher scalability with fewer threads—generally one per CPU
core.
By applying a technique known as event looping these frameworks are
able to handle many requests per thread, making the per-connection
cost more economical.
Working with Spring WebFlux
Spring 5 has introduced a non-blocking, asynchronous web
framework based largely on its Project Reactor to address
the need for greater scalability in web applications and APIs.
Spring WebFlux
a reactive web framework for Spring.
sibling to Spring MVC and shares many of its core components.
Spring WebFlux
On the left side, you see the Spring MVC stack that was introduced in version 2.5 of the Spring
Framework. Spring MVC sits atop the Java Servlet API, which requires a servlet container (such as
Tomcat) to execute on.
By contrast, Spring WebFlux (on the right side) doesn’t have ties to the Servlet API, so it builds on top
of a Reactive HTTP API, which is a reactive approximation of the same functionality provided by the
Servlet API. And because Spring WebFlux isn’t coupled to the Servlet API, it doesn’t require a servlet
container to run on. Instead, it can run on any non-blocking web container including Netty, Undertow,
Tomcat, Jetty
Spring WebFlux
Dependency required
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Spring Reactive WebFlux Application with MySQL
Database
spring.r2dbc.url=r2dbc:mysql://localhost:3306/karunya
spring.r2dbc.username=root
spring.r2dbc.password=
Create Employee class
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
@Table
public class Employee {
@Id
private int id;
private String name;
private int salary;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
}
Create EmployeeRepository interface
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends ReactiveCrudRepository<Employee, Integer>
{
ReactiveCrudRepository<Employee, Integer>
• Interface for create, read, update, delete operations on a repository for a
specific table.
• This repository follows reactive paradigms and uses Project Reactor types
which are built on top of Reactive Streams.
Create Rest Controller
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@RestController
public class EmployeeController {
@Autowired
private EmployeeRepository employeeRepository;
@GetMapping("/getAll")
public Flux<Employee> getAllEmployees(){
Flux<Employee> fluxdata = employeeRepository.findAll();
return fluxdata;
}
@GetMapping("/getEmployee/{id}")
public Mono<Employee> findEmployee(@PathVariable int id)
{
Mono<Employee> monodata = employeeRepository.findById(id);
return monodata;
}
@PostMapping("/addNewEmployee")
public Mono<Employee> createEmployee(@RequestBody Employee emp){
return employeeRepository.save(emp);
}
@DeleteMapping("/deleteEmployee/{id}")
public Mono<Void> removeEmployee(@PathVariable int id){
return employeeRepository.deleteById(id);
}
}
Test API http://localhost:8080/getAll
http://localhost:8080/getEmployee/103
http://localhost:8080/addNewEmployee
http://localhost:8080/deleteEmployee/221
Consuming REST APIs reactively
Using WebClient
WebClient
Spring 5 offers WebClient as a reactive alternative to RestTemplate.
WebClient lets you both send and receive reactive types when
making requests to external APIs asynchronously.
How to use WebClient?
Create an instance of WebClient (or inject a WebClient bean)
Specify the HTTP method of the request to send
Specify the URI and any headers that should be in the request
Submit the request
Consume the response
WebClient class Methods
get()
To fetch either collection of resources (Flux) or a singular resource
(Mono).
post()
Used for creating a new data (Mono) in a table
put()
Used for updating existing data (Mono) in a table
delete()
Used for deleting existing data (Mono) in a table
@Table
public class Employee {
@Id
private int id;
private String name;
private int salary;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
public class ConsumeAPIDemo {
public void findEmployee() {
WebClient webclient = WebClient.create();
Mono<Employee> monoemp = webclient.get()
.uri("http://localhost:8080/getEmployee/{id}",222)
.retrieve()
.bodyToMono(Employee.class);
monoemp.subscribe(System.out :: println);
}
}
For Testing
Call the function from main method
@SpringBootApplication
public class TestReactiveApplication {
public static void main(String[] args) {
new ConsumeAPIDemo().findEmployee();
SpringApplication.run(TestReactiveApplication.class, args);
}
}
Consume Reactive Rest API - GET
To view all the Employees
Generally, we will use GET API to fetch either collection of resources or a singular resource.
HTTP GET /employees : collection of employees as Flux
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;