Spring webflux – Stepping into reactive web development

Reactive programming is awesome, have you try it? I remember that I built an android app few years back using RxJava with Retrofit, it was a pleasant experience, although I haven’t done it in server side. This is going to be my first experience of using spring webflux, as they call “Web on Reactive Stack”. So let’s get into it.

Why reactive approach?

Good old imperative style of programming served us tremendously. But things have changed now, faster cpus, cloud computing and serverless has opened so many capabilities that made people to seek newer approaches of programming. Non Blocking IO, reactive streams are getting lot more attention over past years. So as programmers we need to be on the same page otherwise we would be isolated and left aside.

Reactive web development in java

Java has introduced Flow type in JDK 9 and open the door to platform level reactive programming, there are lambdas so we could do it in functional way. Also kotlin, a jvm language now has something called co routines (we can say light weight threads at a glance) and also java is getting upto speed with loom project. Now things are going to be changed and java is ready for reactive programming now more than ever. Spring also came into functional reactive paradigm with spring 5, webflux is the reactive non blocking offering that is similar to its imperative counterpart spring-webmvc. So why waiting, let’s get started.

I’m going to use java 14 and maven as the build system. I just want to get started, serve first endpoint and hit it, what about you? If you are in same page, let’s create the project by using spring initializr, because I am lazy. Here is my configuration if you want to follow along. I’m going to use spring boot to get things up and running more quickly.

Spring webflux – reactive components

I hope you remember in spring mvc we had controllers (backed by blocking spring rest template) and same way we could use for reactive approach instead of that I am going to explore the functional style, the trendy way. There are two classes comes from reactor, the reactive library used for webflux by default. Mono is the first one which represent emit of one element or an error, Flux which represents many emits and completes with success or an error. If you are not familiar with emitting, stream, subscription and so on, please have a look at reactive manifesto and reactive streams.

Spring webflux – application components

First we have handler functions, which is responsible to consume server request and server response. To serve, it may do other operations such as any business logic, database calls and so on. This would be a implementation of HandlerFunction interface from webflux.

Then we have router functions, basically its similar to the request mapping in spring web mvc. Same as request mapping we could setup different routing and use handlers to serve the route. And this function would be a implementation of RouterFunction interface from webflux.

Finally we have web client which is equivalent to the web mvc rest template but non blocking, you can use it for call blocking api if you want.

package com.aptkode.example.webflux;

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 GreetingHandler {

    Mono<ServerResponse> hello(ServerRequest request){
        return ServerResponse
                .ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue("{ message: \"Hello world\" }"));
    }

}

This is our first handler, this could have many handler methods or just one depending on its responsibility for the application scope.

package com.aptkode.example.webflux;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
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;

@Component
public class GreetingRouter {

    @Bean
    RouterFunction<ServerResponse> route(GreetingHandler handler){
        return RouterFunctions.route(RequestPredicates.GET("/hello"), handler::hello);
    }

}

This is first router, note that it is annotated with @Bean, meaning this is available in spring context as an bean and every method name should be identical otherwise you need to name it. So you could have many routers in single router class. Next we should have our web client ready.

package com.aptkode.example.webflux;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.reactive.function.client.WebClient;

@SpringBootApplication
public class SpringBootWebfluxApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootWebfluxApplication.class, args);
		WebClient.create("http://localhost:8080");
	}

}

This is it. Run main method and it just works. One thing I noticed that its startup time is very fast, it may get increased if I had some data sources and etc. But still its fast I think which would be a good thing for microservices application.

spring web application startup log
startup time

Default configuration

Here we didn’t do any thing to tweak the default behavior of the spring boot stater. So it uses netty as the http runtime and it support tomcat, undertow and servlet 3.1+ containers. Also underlying default reactive library is reactor we could use other library such as RxJava and we’ll take a look at how to do these tweaks in future article.

It works

Application is running on localhost port 8080, and it serves our route hello. If we hit it, we get hello world message. This is the beginning, explore it. I will publish more stuff regarding spring webflux because its awesome. I am planing to use this for spring cloud gcp firestore data repository pattern exploring. Which would be a continuation of my last GCP article on Firestore querying with spring cloud gcp. Happy Coding.

Leave a Comment

Your email address will not be published. Required fields are marked *