Introduction of Spring Webflux and How to Apply Cloud on It
In this article, see an introduction of Spring Webflux and see how to apply Cloud on it.
Join the DZone community and get the full member experience.
Join For FreeIf you're looking for a non-blocking web stack to handle concurrency with a small number of threads and scale with fewer hardware resource Spring WebFlux is for you. In this article, we'll talk about Spring WebFlux and how to move this non-block project to the cloud thanks to Platform.sh.
The reactive-stack web framework, Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports Reactive Streams back pressure, and runs on such servers as Netty, Undertow, and Servlet 3.1+ containers.
Reactive programming is an asynchronous programming paradigm concerned with data streams and the propagation of change. This means that it becomes possible to express static (e.g. arrays) or dynamic (e.g. event emitters) data streams with ease via the employed programming language(s).
The Spring Framework uses the Reactor internally for its own reactive support. Reactor is a Reactive Streams implementation that further extends the basic Reactive Streams Publisher contract with the Flux and Mono composable API types to provide declarative operations on data sequences of 0..N and 0..1.
Give a brief introduction and about what is Spring Webflux, to demonstrate it, we'll create a simple application that handles people, but we won't handle the database we'll talk about it in the next article.
We'll create a maven project, and the first step is a pom.xml to set the Spring Webflux dependencies.
x
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sh.platform.example</groupId>
<artifactId>template-spring-webflux</artifactId>
<version>0.0.1</version>
<properties>
<platform.sh.version>2.2.3</platform.sh.version>
<java.version>11</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>sh.platform</groupId>
<artifactId>config</artifactId>
<version>${platform.sh.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>spring-reactive</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>oss.sonatype.org-snapshot</id>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
</project>
Our model is really smooth, it has three attributes: id, name, and age. To point out, we won't use a database we'll create it on memory.
x
public class Person {
private Long id;
private String name;
private Integer age;
//getter and setter
}
Spring WebFlux supports the annotation-based configurations in the same way as the Spring Web MVC framework.
Spring WebFlux supports the annotation-based configurations in the same way as the Spring Web MVC framework. Therefore, it will be easier for you if you already know Spring MVC. What change are the returns as you can see, it will return either Mono or Flux.
Spring WebFlux provides the Mono and Flux API types to work on data sequences of 0..1 (Mono) and 0..N (Flux) through a rich set of operators aligned with the ReactiveX vocabulary of operators.
xxxxxxxxxx
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
"people") (
public class PersonController {
private PersonRepository repository;
code = HttpStatus.CREATED) (
public Mono<String> save( Person person) {
repository.save(person);
return Mono.just("Saved- " + person.getName());
}
value = "/{id}", produces = "application/json") (
public Mono<Person> get( ("id") long id) {
return repository.findById(id);
}
produces = "application/json") (
public Flux<Person> get() {
return repository.findAll();
}
value = "/{id}", produces = "application/json") (
public Mono<Person> update( ("id") long id, Person person) {
repository.save(person);
return Mono.just(person);
}
value = "/{id}", produces = "application/json") (
public Mono<Person> delete( ("id") long id) {
return repository.findById(id);
}
}
The Java application is ready to go! Let's move it to the cloud easily with Platform.sh. Platform.sh is a second-generation Platform-as-a-Service built especially for continuous deployment.
It allows you to host web applications on the cloud while making your development and testing workflows more productive.
As a Platform as a Service, or PaaS, Platform.sh automatically manages everything your application
needs in order to run. That means you can, and should, view your infrastructure needs as part of
your application, and version-control it as part of your application.
Every application you deploy on Platform.sh is built as a virtual cluster, containing a set of containers. There are three types of containers within your cluster:
- One Router (.platform/routes.yaml). Platform.sh allows you to define the routes.
xxxxxxxxxx
"https://{default}/":
type upstream
upstream"app:http"
"https://www.{default}/"
type redirect
to"https://{default}/"
- Zero or more service containers (.platform/services.yaml). Platform.sh allows you to completely define and configure the topology and services you want to use on your project.
- One or more application containers (.platform.app.yaml). You control your application and the way it will be built and deployed on Platform.sh via a single configuration file.
xxxxxxxxxx
name app
type"java:11"
disk1024
hooks
build mvn clean install
web
commands
start
java -jar -Xmx$(jq .info.limits.memory /run/config.json)m -XX:+ExitOnOutOfMemoryError \
target/spring-reactive.jar --server.port=$PORT
The application is now ready, so it’s time to move it to the cloud with Platform.sh using the following steps:
- Create a new free trial account.
- Sign up with a new user and password, or login using a current GitHub, Bitbucket, or Google account. If you use a third-party login, you’ll be able to set a password for your Platform.sh account later.
- Select the region of the world where your site should live.
- Select the blank template.
You have the option to either integrate to GitHub, GitLab, or Platfrom.sh will provide to you. Finally, push to the remote repository:
xxxxxxxxxx
git remote add platform <platform.sh@gitrepository>
git commit -m "Initial project"
git push -u platform master
Done, we have a simple and nice Spring Webflux application and ready to go to the cloud.
Opinions expressed by DZone contributors are their own.
Comments