Introduction to Spring WebFlux Framework

0
196

Spring Webflux framework is a new reactive framework introduced in Spring 5.0 for creating reactive web applications. Reactive programming is becoming increasingly popular with time and it is good to hear that Spring has embraced the need and introduced the built-in reactive web support.What is Reactive Programming??

What is Reactive Programming ?

Reactive programming is asynchronous and event-based programming. Reactive programming is simply to program using, and relying on, events instead of the order of lines in the code.

Usually this involves more than one event, and those events happen in a sequence over time. We call this sequence of events a “stream”.

Think of events as anything that might happen in the future. For example, you know that Jane (a store owner) is always tweeting interesting stuff on Twitter, every time she tweets something we call that an “event”.

If you look at Jane’s twitter feed, you have a sequence of “events” happening over time (a stream of events). Reactive programming is named so because we get to “react” to those events.

For example, imagine that you’re waiting for Jane to tweet a promotional code about something cool she sells in her store, and you want to “react” to that tweet, and buy the cool thing, using the promotional code. In a simplified picture, that’s exactly what Reactive programming is all about.

To be able to react to an event, we have to be monitoring it. If we don’t monitor the event, we’ll never know when to react to it. On Twitter, to monitor the events of Jane tweeting, we follow Jane and set our phone to notify us every time she tweets. When she does, we look at the tweet and make a decision if we need to further react on it or not.

In Reactive Programming, the process of monitoring an event is known as listening or subscribing to the event. In the above example, we are the subscriber and Jane is the publisher.

Spring MVC (vs) Spring WebFlux Framework

Spring MVC Framework is for developing web applications and Spring WebFlux framework is for developing reactive web applications and sits next to each other. However, the main difference is that unlike Spring MVC which is synchronous, Spring WebFlux is fully asynchronous and non-blocking and it implements the Reactive Streams specification through Reactor Project.

This image has an empty alt attribute; its file name is image-6-711x1024.png
Spring Web-flux Framework

Reactive Streams

Main components of Reactive stream specification are :

  • Publisher: The publisher is the source that will send the data to one or more subscribers.
  • Subscriber: A subscriber will subscribe itself to a publisher, will indicate how much data the publisher may send and will process the data.
  • Processor: A processor can be used to sit between a publisher and a subscriber, this way a transformation of the data can take place.

Reactor Project

  • It is an implementation of Reactive streams specification.
  • Spring Webflux is based on Reactor Project.
  • Reactor provides two types:
    • Mono: implements Publisher and returns 0 or 1 elements;
    • Flux: implements Publisher and returns N elements.

Developing Spring Webflux Rest service

a. Add Maven Dependency:

  • Add spring-boot-starter-webflux module to your application pom.xml
Web-flux dependency

Note: If both spring-boot-starter-web and spring-boot-starter-webflux are present in pom.xml, then Spring Boot autoconfigures Spring MVC, and not WebFlux. You can still override this behavior to auto-configure the webflux framework by setting the chosen application type to: SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE).

  • Netty is the default embedded server used for Spring Webflux applications.
  • Spring WebFlux comes in two flavors: Functional and Annotation-based.
  • Let us see how to use each of these flavors in detail by creating a simple “Hello World” Reactive Rest service

Functional based Spring Webflux Configuration

Router:

  • Router methods are used to define the routes for the requests reaching the application.
  • In this example, we are routing the GET request for /helloWorld to route to the helloWorld() method in the HelloWorldHandler class. Also, it is specified that the client should accept plain text response.
  • A Sample code snippet below:
package com.example.demo.router;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import com.example.demo.handler.ApplicationHandler;
@Configuration
public class ApplicationRouter {
@Bean
public RouterFunction<ServerResponse> routeHelloWorld(ApplicationHandler helloWorldHandler) {
return RouterFunctions.route(RequestPredicates.GET("/helloWorld").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),helloWorldHandler::helloWorld);
  }
}

Handler:

  • Handler is used to handle the requests that are routed to this method by the router. It returns either a Mono or Flux response.
  • In this example, the handler method is simply returning a plain text message “Hello World!”. However, in a real-world application, this can be a complex operation (for example, to query DB and return a set of items etc…)
package com.example.demo.handler;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@Component
public class ApplicationHandler {
  public Mono<ServerResponse> helloWorld(ServerRequest request) {
    return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
      .body(BodyInserters.fromObject("Hello World!"));
  }
}

Main Class:

  • No specific logic written here, just used for bootstrapping the spring boot application.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }
}

Right Click and run as a Java application:

Notice the following output in the console that the default web-flux servlet container: NETTY got started up successfully on port:8080


Now, hit the URL: http://localhost:8080/helloWorld

Annotation-based Spring Web-flux Configuration

Spring WebFlux supports the annotation-based configurations in the same way as Spring Web MVC framework.

Creating a Reactive RestController:

package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/helloWorld")
public class ApplicationController {
 
  @GetMapping("/welcome")
  private Mono<String> getMessage() {
    return Mono.just("Hello World!!");
  }   
}

Note that the above controller class returns a simple plain text message “Hello World !!!” when you run the application and hit the URL:

http://localhost:8080/helloWorld/welcome

Application Structure

Application Structure

Conclusion

In this tutorial, we have seen how to create a Simple Reactive Spring Boot Application and the main components present in the Reactive Framework.

It is nice to see that the widely used Spring Boot is going towards Reactive Programming model. However, if the underlying technologies used in the Spring Boot are not totally reactive, then we cannot leverage the complete advantages of Reactive model and the application is not truly reactive.

For example, if the Relational Databases used in the Spring Boot application is not reactive (Hibernate API is not reactive because it is dependent on JDBC which is not reactive), then the application is not truly reactive.

In the subsequent tutorials, we are going to learn about the various DB technologies that can be used in a Spring Boot framework.

References

https://spring.io/guides/gs/reactive-rest-service/

LEAVE A REPLY

Please enter your comment!
Please enter your name here