StackStalk
  • Home
  • Java
    • Java Collection
    • Spring Boot Collection
  • Python
    • Python Collection
  • C++
    • C++ Collection
    • Progamming Problems
    • Algorithms
    • Data Structures
    • Design Patterns
  • General
    • Tips and Tricks

Monday, January 17, 2022

Reactive Programming with Spring WebFlux

 January 17, 2022     Java, Microservices     No comments   

This article will focus on how to do reactive programming with Spring WebFlux. It starts with introductory concepts around reactive programming, reactive streams specification, project reactor and Spring WebFlux. We will work on an example to build a simple loan info microservice to demonstrate the concepts.

Reactive Programming

Reactive programming paradigm is about asynchronous and non-blocking applications. Reactive programming is good for applications that have large streaming data and needs resiliency under high load. In this model, data is pushed to the clients as and when it is available.

Handling streams of data whose volume is unknown (e.g. live data) requires special care in an asynchronous system. The most prominent issue is that resource consumption needs to be controlled such that a fast data source does not overwhelm the stream destination referred as backpressure.


Reactive Streams Specification

Reference:http://www.reactive-streams.org/
Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure. The scope of Reactive Streams is to find a minimal set of interfaces, methods and protocols that will describe the necessary operations and entities to achieve the goal—asynchronous streams of data with non-blocking back pressure.

Reactive streams interfaces.
Processor<T,​R>
A Processor represents a processing stage—which is both a Subscriber and a Publisher and obeys the contracts of both.
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
}
Publisher<T>
A Publisher is a provider of a potentially unbounded number of sequenced elements, publishing them according to the demand received from its Subscriber(s).
public interface Publisher<T> {
  
    public void subscribe(Subscriber<? super T> s);
}
Subscriber<T>
Will receive call to Subscriber.onSubscribe(Subscription) once after passing an instance of Subscriber to Publisher.subscribe(Subscriber).
public interface Subscriber<T> {

    public void onSubscribe(Subscription s);
    public void onNext(T t);
    public void onError(Throwable t);
    public void onComplete();
}
Subscription
A Subscription represents a one-to-one lifecycle of a Subscriber subscribing to a Publisher.
public interface Subscription {

    public void request(long n);
    public void cancel();
}
Reactive Streams Publisher Subscriber Flow
The reactive streams publisher subscriber flow starts with a subscribe() request towards the publisher to start streaming the data. This starts a new Subscription. Followed by this a demand is made to the publisher with the number of elements using the request() method. onNext() is the data notification sent from the publisher. onComplete() is the successful terminal state.
 

Project Reactor

Reference: https://projectreactor.io/

Project Reactor is a library (reactor-core) based on the Reactive Streams specification, for building non-blocking applications on the JVM. Reactor is fully non-blocking and provides efficient demand management in the form of managing "backpressure".
Reactor introduces composable reactive types that implement Publisher but also provide a rich vocabulary of operators: Flux and Mono. 
  • Flux object represents a reactive sequence of 0..N items 
  • Mono object represents a single-value-or-empty (0..1) result

Flux

A Flux is a reactive type, standard Publisher that represents an asynchronous sequence of 0 to N emitted items, optionally terminated by either a completion signal or an error. Simple example below to demonstrate usage and signals of Flux.
package com.stackstalk;

import java.util.List;

import reactor.core.publisher.Flux;

public class ReactorTestMain {
	
	public Flux<String> loanTypesFlux() {
		return Flux.fromIterable(List.of("Car Loan", "Education Loan", "Personal Loan")).log();
	}

	public static void main(String[] args) {
		ReactorTestMain reactorTestMain = new ReactorTestMain();
		reactorTestMain.loanTypesFlux().subscribe(name -> {
			System.out.println(name);
		});
	}
}
Output:
[ INFO] (main) | onSubscribe([Synchronous Fuseable] FluxIterable.IterableSubscription)
[ INFO] (main) | request(unbounded)
[ INFO] (main) | onNext(Car Loan)
Car Loan
[ INFO] (main) | onNext(Education Loan)
Education Loan
[ INFO] (main) | onNext(Personal Loan)
Personal Loan
[ INFO] (main) | onComplete()

Mono

Mono object is a reactive type and represents a single value or empty (0..1) result. A Mono is a specialized Publisher that emits atmost one item via onNext signal then terminates with an onComplete signal. Simple example below to demonstrate usage and signals of Mono.
package com.stackstalk;

import java.util.List;

import reactor.core.publisher.Mono;

public class ReactorTestMain {
	
	public Mono<String> strMono() {
		return Mono.just("Hello World!!").log();
	}

	public static void main(String[] args) {
		ReactorTestMain reactorTestMain = new ReactorTestMain();
		reactorTestMain.strMono().subscribe(name -> {
			System.out.println(name);
		});
	}
}
Output:
[ INFO] (main) | onSubscribe([Synchronous Fuseable] Operators.ScalarSubscription)
[ INFO] (main) | request(unbounded)
[ INFO] (main) | onNext(Hello World!!)
Hello World!!
[ INFO] (main) | onComplete()

Spring WebFlux

Reference: https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html

Original web framework included in Spring Framework is Spring MVC built for servlet API and servlet containers. Spring WebFlux added later, is the reactive-stack web framework which is fully non-blocking, supports reactive streams back pressure and runs on non-blocking servers such as Netty, Undertow etc. Spring WebFlux is built on top of project reactor.

One of the key differences between Spring MVC and Spring WebFlux is the concurrency model.
  • In Spring MVC (and servlet applications in general), it is assumed that applications can block the current thread, (for example, for remote calls). For this reason, servlet containers use a large thread pool to absorb potential blocking during request handling.
  • In Spring WebFlux (and non-blocking servers in general), it is assumed that applications do not block. Therefore, non-blocking servers use a small, fixed-size thread pool (event loop workers) to handle requests.

Spring WebFlux provides two programming models. 
  • Annotated Controllers: Consistent with Spring MVC and based on the same annotations from the spring-web module. Both Spring MVC and WebFlux controllers support reactive return types.
  • Functional Endpoints: Lambda-based, lightweight, and functional programming model. This is a small library or a set of utilities that an application can use to route and handle requests.
We will see each of these programming models with an example.

Spring WebFlux Example using Annotation based programming
Spring WebFlux Example using Functional Programming

Conclusion


In this section we looked at reactive programming in general and understood couple of programming models with Spring WebFlux namely, annotation-based approach and functional endpoints approach.

When to use Spring MVC or Spring WebFlux is a common question.
  • If there is a Spring MVC application that works fine, there is no need to change. Imperative programming is the easiest way to write, understand, and debug code. If the application has blocking dependencies it is better to stay with Spring MVC.
  • Spring WebFlux is a good fit for uses cases that require ease of streaming up or down. If there is a need for lightweight, functional web framework for use with Java 8 lambdas, we can use the Spring WebFlux functional web endpoints. In a microservice architecture, we can always have a mix of applications with either Spring MVC or Spring WebFlux controllers or with Spring WebFlux functional endpoints.
  • Share This:  
Newer Post Older Post Home

0 comments:

Post a Comment

Follow @StackStalk
Get new posts by email:
Powered by follow.it

Popular Posts

  • Avro Producer and Consumer with Python using Confluent Kafka
    In this article, we will understand Avro a popular data serialization format in streaming data applications and develop a simple Avro Produc...
  • Monitor Spring Boot App with Micrometer and Prometheus
    Modern distributed applications typically have multiple microservices working together. Ability to monitor and manage aspects like health, m...
  • Server-Sent Events with Spring WebFlux
    In this article we will review the concepts of server-sent events and work on an example using WebFlux. Before getting into this article it ...
  • Implement caching in a Spring Boot microservice using Redis
    In this article we will explore how to use Redis as a data cache for a Spring Boot microservice using PostgreSQL as the database. Idea is to...
  • Python FastAPI microservice with Okta and OPA
    Authentication (AuthN) and Authorization (AuthZ) is a common challenge when developing microservices. In this article, we will explore how t...
  • Spring Boot with Okta and OPA
    Authentication (AuthN) and Authorization (AuthZ) is a common challenge when developing microservices. In this article, we will explore how t...
  • Getting started with Kafka in Python
    This article will provide an overview of Kafka and how to get started with Kafka in Python with a simple example. What is Kafka? ...
  • Getting started in GraphQL with Spring Boot
    In this article we will explore basic concepts on GraphQL and look at how to develop a microservice in Spring Boot with GraphQL support. ...

Copyright © StackStalk