{{announcement.body}}
{{announcement.title}}

Introduction of Spring Webflux and How to Apply Cloud on It

DZone 's Guide to

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.

· Java Zone ·
Free Resource

If 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.

XML
 




x


1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4
   <modelVersion>4.0.0</modelVersion>
5
 
          
6
   <groupId>sh.platform.example</groupId>
7
   <artifactId>template-spring-webflux</artifactId>
8
   <version>0.0.1</version>
9
 
          
10
   <properties>
11
    <platform.sh.version>2.2.3</platform.sh.version>
12
    <java.version>11</java.version>
13
</properties>
14
 
          
15
<parent>
16
    <groupId>org.springframework.boot</groupId>
17
    <artifactId>spring-boot-starter-parent</artifactId>
18
    <version>2.2.6.RELEASE</version>
19
</parent>
20
 
          
21
<dependencies>
22
    <dependency>
23
        <groupId>org.springframework.boot</groupId>
24
        <artifactId>spring-boot-starter-webflux</artifactId>
25
    </dependency>
26
    <dependency>
27
        <groupId>sh.platform</groupId>
28
        <artifactId>config</artifactId>
29
        <version>${platform.sh.version}</version>
30
    </dependency>
31
    <dependency>
32
        <groupId>org.springframework.boot</groupId>
33
        <artifactId>spring-boot-starter-test</artifactId>
34
        <scope>test</scope>
35
    </dependency>
36
</dependencies>
37
 
          
38
<build>
39
    <finalName>spring-reactive</finalName>
40
    <plugins>
41
        <plugin>
42
            <groupId>org.springframework.boot</groupId>
43
            <artifactId>spring-boot-maven-plugin</artifactId>
44
        </plugin>
45
    </plugins>
46
</build>
47
 
          
48
<repositories>
49
    <repository>
50
        <id>oss.sonatype.org-snapshot</id>
51
        <url>http://oss.sonatype.org/content/repositories/snapshots</url>
52
    </repository>
53
</repositories>
54
</project>
55
 
          



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.

Java
 




x


1
public class Person {
2
 
          
3
    private Long id;
4
 
          
5
    private String name;
6
 
          
7
    private Integer age;
8
  //getter and setter 
9
}



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. 

Java
 




xxxxxxxxxx
1
54


 
1
 
          
2
import org.springframework.beans.factory.annotation.Autowired;
3
import org.springframework.http.HttpStatus;
4
import org.springframework.web.bind.annotation.DeleteMapping;
5
import org.springframework.web.bind.annotation.GetMapping;
6
import org.springframework.web.bind.annotation.PathVariable;
7
import org.springframework.web.bind.annotation.PostMapping;
8
import org.springframework.web.bind.annotation.PutMapping;
9
import org.springframework.web.bind.annotation.RequestBody;
10
import org.springframework.web.bind.annotation.RequestMapping;
11
import org.springframework.web.bind.annotation.ResponseStatus;
12
import org.springframework.web.bind.annotation.RestController;
13
import reactor.core.publisher.Flux;
14
import reactor.core.publisher.Mono;
15
 
          
16
 
          
17
@RestController
18
@RequestMapping("people")
19
public class PersonController {
20
 
          
21
    @Autowired
22
    private PersonRepository repository;
23
 
          
24
 
          
25
    @PostMapping
26
    @ResponseStatus(code = HttpStatus.CREATED)
27
    public Mono<String> save(@RequestBody Person person) {
28
        repository.save(person);
29
        return Mono.just("Saved- " + person.getName());
30
    }
31
 
          
32
    @GetMapping(value = "/{id}", produces = "application/json")
33
    public Mono<Person> get(@PathVariable("id") long id) {
34
        return repository.findById(id);
35
    }
36
 
          
37
    @GetMapping(produces = "application/json")
38
    public Flux<Person> get() {
39
        return repository.findAll();
40
    }
41
 
          
42
 
          
43
    @PutMapping(value = "/{id}", produces = "application/json")
44
    public Mono<Person> update(@PathVariable("id") long id, @RequestBody Person person) {
45
        repository.save(person);
46
        return Mono.just(person);
47
    }
48
 
          
49
    @DeleteMapping(value = "/{id}", produces = "application/json")
50
    public Mono<Person> delete(@PathVariable("id") long id) {
51
        return repository.findById(id);
52
    }
53
}
54
 
          



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.
YAML
 




xxxxxxxxxx
1


 
1
"https://{default}/":
2
  type: upstream
3
  upstream: "app:http"
4
 
          
5
"https://www.{default}/":
6
  type: redirect
7
  to: "https://{default}/"
8
 
          



  • 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.
YAML
 




xxxxxxxxxx
1
11


1
name: app
2
type: "java:11"
3
disk: 1024
4
hooks:
5
    build: mvn clean install
6
web:
7
    commands:
8
        start:  |
9
           java -jar -Xmx$(jq .info.limits.memory /run/config.json)m -XX:+ExitOnOutOfMemoryError \
10
           target/spring-reactive.jar --server.port=$PORT
11
 
          



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:

Shell
 




xxxxxxxxxx
1


 
1
git remote add platform <platform.sh@gitrepository>
2
git commit -m "Initial project"
3
git push -u platform master



Done, we have a simple and nice Spring Webflux application and ready to go to the cloud.

Topics:
cloud (add topic) ,java ,paas ,reactive ,spring ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}