Getting Started with Spring WebFlux — Bootstrapping a Reactive Web Application with Spring Initializr

Alexander Obregon
4 min readApr 23, 2023

--

Image Source

Introduction

In this article, we will walk through the process of creating a reactive web application using Spring WebFlux and Spring Boot. Spring WebFlux is a reactive framework that provides support for non-blocking, asynchronous web applications, making it perfect for modern, scalable applications. We will use Spring Initializr, an online service, to create a boilerplate project to get started quickly.

Prerequisites: Before diving into the tutorial, make sure you have the following tools installed:

  • JDK 11 or later
  • Maven or Gradle (we will use Maven in this example)
  • A suitable IDE, such as IntelliJ IDEA or Eclipse

Step 1: Generate the project using Spring Initializr

Head over to the Spring Initializr website. Configure the following options for your project:

  • Project type: Maven Project
  • Language: Java
  • Packaging: Jar
  • Java version: 11
  • Group: com.example
  • Artifact: reactive-webapp
  • Name: reactive-webapp
  • Description: A simple reactive web application using Spring WebFlux
  • Package name: com.example.reactive-webapp

In the “Dependencies” section, search for “WebFlux” and select “Reactive Web” to include Spring WebFlux in your project. Click on “Generate” to download the zipped project files.

Step 2: Import and explore the project

Extract the downloaded project files and import them into your favorite IDE. You should see a basic structure similar to the following:

reactive-webapp/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com.example.reactive-webapp/
│ │ │ └── ReactiveWebappApplication.java
│ │ └── resources/
│ │ ├── static/
│ │ ├── templates/
│ │ └── application.properties
│ └── test/
│ └── java/
│ └── com.example.reactive-webapp/
│ └── ReactiveWebappApplicationTests.java
├── .gitignore
├── pom.xml
└── README.md

Step 3: Implement a simple reactive endpoint

In ReactiveWebappApplication.java, add a new RouterFunction bean to define a simple reactive endpoint:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;

@SpringBootApplication
public class ReactiveWebappApplication {

public static void main(String[] args) {
SpringApplication.run(ReactiveWebappApplication.class, args);
}

@Bean
public RouterFunction<ServerResponse> routeHelloWorld() {
return route(GET("/hello"),
request -> ServerResponse.ok()
.contentType(MediaType.TEXT_PLAIN)
.body(Mono.just("Hello, Reactive World!"), String.class));
}
}

Step 4: Run the application

Run the ReactiveWebappApplication class from your IDE or use Maven to start the application:

$ cd reactive-webapp
$ mvn spring-boot:run

After the application starts, navigate to http://localhost:8080/hello in your browser or use a tool like curl to test the endpoint:

$ curl http://localhost:8080/hello

You should see the response “Hello, Reactive World!”.

Step 5: Create a simple reactive RESTful API

Now, let’s create a simple reactive RESTful API to demonstrate the power of Spring WebFlux. We’ll create a Person class and a PersonHandler class to handle the API requests.

First, create a new Person class in the com.example.reactive-webapp package:

package com.example.reactive-webapp;

public class Person {
private final String id;
private final String name;

public Person(String id, String name) {
this.id = id;
this.name = name;
}

public String getId() {
return id;
}

public String getName() {
return name;
}
}

Next, create a new PersonHandler class in the same package:

package com.example.reactive-webapp;

import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

public class PersonHandler {
private final Map<String, Person> personMap = new HashMap<>();

public Mono<ServerResponse> getAllPeople(ServerRequest request) {
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(Flux.fromIterable(personMap.values()), Person.class);
}

public Mono<ServerResponse> getPerson(ServerRequest request) {
String personId = request.pathVariable("id");
Person person = personMap.get(personId);
if (person != null) {
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(person), Person.class);
} else {
return ServerResponse.notFound().build();
}
}

public Mono<ServerResponse> createPerson(ServerRequest request) {
Mono<Person> personMono = request.bodyToMono(Person.class);
return personMono.flatMap(person -> {
personMap.put(person.getId(), person);
return ServerResponse.created(request.uriBuilder().pathSegment(person.getId()).build().toUri())
.contentType(MediaType.APPLICATION_JSON)
.body(Mono.just(person), Person.class);
});
}
}

Finally, update the ReactiveWebappApplication class to include the new API endpoints:

import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;

import static org.springframework.web.reactive.function.server.RequestPredicates.*;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;

// ... other imports and class definition ...

@Bean
public RouterFunction<ServerResponse> personRoutes(PersonHandler handler) {
return route(GET("/people"), handler::getAllPeople)
.andRoute(GET("/people/{id}"), handler::getPerson)
.andRoute(POST("/people"), handler::createPerson);
}

@Bean
public PersonHandler personHandler() {
return new PersonHandler();
}

Step 6: Test the RESTful API

Run the application again and use a tool like curl or Postman to test the new RESTful API endpoints. For example:

  • To create a new person:
$ curl -X POST -H "Content-Type: application/json" -d '{"id": "1", "name": "John Doe"}' http://localhost:8080/people
  • To retrieve all people:
$ curl http://localhost:8080/people
  • To retrieve a specific person by ID:
$ curl http://localhost:8080/people/1

Conclusion

We have demonstrated how to create a simple reactive web application using Spring WebFlux and Spring Boot. We used Spring Initializr to generate the project structure and implemented a simple reactive endpoint and a reactive RESTful API. This is just the beginning of what you can achieve with Spring WebFlux. As you build more complex applications, you can take advantage of the full power of reactive programming, allowing you to create highly scalable and responsive web applications.

  1. The Official Spring WebFlux Documentation
  2. Baeldung’s Spring WebFlux Tutorial Series
Spring Boot icon by Icons8

--

--

Alexander Obregon

Software Engineer, fervent coder & writer. Devoted to learning & assisting others. Connect on LinkedIn: https://www.linkedin.com/in/alexander-obregon-97849b229/