---
title: "Spring WebFlux: A Quick Start"
description: Your quick start guide for building reactive REST APIs with Spring WebFlux.
image: https://blog.avenuecode.com/hubfs/spring-featured-image.png
---

[AvenueCode.com](https://avenuecode.com) [News](https://avenuecode.com/news) [Contact](https://avenuecode.com/contact)

[![Avenue Code Snippets Logo](https://blog.avenuecode.com/hubfs/Avenue%20Code%20New%20Logos%20-%202023/AC-Snippets---Black.png)](https://blog.avenuecode.com/?hsLang=en-us) *menu*

- Technology
  
  [Cloud](https://blog.avenuecode.com/blog/topic/cloud?hsLang=en-us) [Delivery Infrastructure](https://blog.avenuecode.com/blog/topic/delivery-infrastructure?hsLang=en-us) [Web Experience](https://blog.avenuecode.com/blog/topic/web-experience?hsLang=en-us) [Agile Mindset](https://blog.avenuecode.com/blog/topic/agile-mindset?hsLang=en-us) [Quality First](https://blog.avenuecode.com/blog/topic/quality-first?hsLang=en-us)
  
  [Design](https://blog.avenuecode.com/blog/topic/design?hsLang=en-us) [Solution Architecture](https://blog.avenuecode.com/blog/topic/solution-architecture?hsLang=en-us) [Data & ML](https://blog.avenuecode.com/blog/topic/data-and-machine-learning?hsLang=en-us) [Mobile Experience](https://blog.avenuecode.com/blog/topic/mobile-experience?hsLang=en-us)
- [Whitepapers](https://blog.avenuecode.com/blog/topic/whitepapers?hsLang=en-us)
- [Spotlight](https://blog.avenuecode.com/blog/topic/spotlight?hsLang=en-us)
- [Extraordinary Women in Tech](https://blog.avenuecode.com/blog/topic/extraordinary-women-in-tech?hsLang=en-us)
- [Avenue Code Culture](https://blog.avenuecode.com/blog/topic/avenue-code-culture?hsLang=en-us)

- [Cloud](https://blog.avenuecode.com/blog/topic/cloud?hsLang=en-us)
- [Design](https://blog.avenuecode.com/blog/topic/design?hsLang=en-us)
- [Delivery Infrastructure](https://blog.avenuecode.com/blog/topic/delivery-infrastructure?hsLang=en-us)
- [Solution Architecture](https://blog.avenuecode.com/blog/topic/solution-architecture?hsLang=en-us)
- [Web Experience](https://blog.avenuecode.com/blog/topic/web-experience?hsLang=en-us)
- [Data & ML](https://blog.avenuecode.com/blog/topic/data-and-machine-learning?hsLang=en-us)
- [Agile Mindset](https://blog.avenuecode.com/blog/topic/agile-mindset?hsLang=en-us)
- [Mobile Experience](https://blog.avenuecode.com/blog/topic/mobile-experience?hsLang=en-us)
- [Quality First](https://blog.avenuecode.com/blog/topic/quality-first?hsLang=en-us)
- [Whitepapers](https://blog.avenuecode.com/blog/topic/whitepapers?hsLang=en-us)
- [Spotlight](https://blog.avenuecode.com/blog/topic/spotlight?hsLang=en-us)
- [Extraordinary Women in Tech](https://blog.avenuecode.com/blog/topic/extraordinary-women-in-tech?hsLang=en-us)
- [Avenue Code Culture](https://blog.avenuecode.com/blog/topic/avenue-code-culture?hsLang=en-us)

# [Spring WebFlux: A Quick Start](https://blog.avenuecode.com/spring-webflux-a-quick-start)

- [Tweet](https://twitter.com/share)

*perm\_identity* [Leonardo Silva](https://blog.avenuecode.com/spring-webflux-a-quick-start/author/leonardo-silva?hsLang=en-us)

*schedule* 10/24/18 5:00 PM

A common problem with the traditional blocking API style is what we call backpressure. Simply put, backpressure is when clients or consumers overwhelm the server's capacity to process requests. This creates the need for efficient hardware and software scaling. Fortunately, Spring WebFlux offers a solution. 

We always want to improve our servers' capacity to process requests, preferably without additional hardware costs. Programming reactively and asynchronously allows us to improve our API's ability to scale vertically with no need for additional nodes in the cluster.

As of September 2017, Spring 5.0 went GA, and one of its most exciting new features is its support for building reactive APIs through the new spring-webflux module. Spring WebFlux provides us with the resources to build a reactive API in a declarative rather than imperative manner. Its two main programming models can be classified into annotated controllers - based on the same annotations from the spring-web module - and functional endpoints, which use lambda expressions and functional style.

Today we'll walk through the steps of building a simple microservice to illustrate the main features of the spring-webflux module using functional endpoints, followed by integration tests to validate the Restful API.

##### Before Starting

Make sure you have Java version 1.8 or later. We are going to use [MongoDB](https://www.mongodb.com/) as our database because Spring provides an out-of-the-box, reactive MongoDB repository implementation for us to use. You can get MongoDB using brew with a simple command:

`$ brew install mongodb`

To start up the server, simply type:

`$ mongod`

##### Setting Up Our Project

- To set up our project, go [here](http://start.spring.io/), select Gradle Project, add Reactive Web and Reactive MongoDB to the dependency list, download the compressed file by clicking on "Generate Project," then extract into your workspace and open the project using your favorite IDE. 

![Screen Shot 2018-07-19 at 5.14.29 PM](https://blog.avenuecode.com/hs-fs/hubfs/Screen%20Shot%202018-07-19%20at%205.14.29%20PM.png?width=866&name=Screen%20Shot%202018-07-19%20at%205.14.29%20PM.png)

##### Database

Next, let's set up our database connection. Fortunately, doing so is as simple as adding the following line to your `application.properties` file.

Now we need to create a POJO to represent the entity we want to save. We are going to use a simple `Book.java` class as our model.

Our DB repository is implemented the same way a traditional JPA repository is. We just need to create an interface that extends the Spring repository implementation. For our purposes, we will be using the `ReactiveMongoRepository` interface, which already contains all the features we need to make our API fully reactive.

##### Controller

Now let's start developing our REST controller. Our controller contains 5 endpoints. We will walk through each one of these to illustrate how reactive concepts are implemented.

##### POST /books

This endpoint adds an entry to our MongoDB database. Notice that we are returning a `Mono` object that wraps the entity that was created. If you look into the `Mono` class definition, you will see that it extends a class called `Publisher`: a `Publisher` is a reactive stream that may send data to one or more subscribers. The subscribers may use the information as it becomes available--that is, they react as the publisher provides information.

##### GET /books

This endpoint is responsible for returning a `Publisher` that hands over all the book instances we have created in our DB. The main difference between this endpoint and the previous one regarding reactivity is the `Publisher` implementation we return. We have used a `Mono` to return the single instance we have just saved, and now we are using a `Flux` to get all the instances we have created until this moment. That's the main difference between a `Flux` and a `Mono`: a `Mono` can omit 0 to 1 instances of the parameterized item, while a `Flux` can omit 0 to n instances.

##### GET books/{isbn}

We now query our books collection to return a single item specified by its primary key: the ISBN. Notice that, in this endpoint, we are wrapping a `ResponseEntity` object into a `Mono` object. We are using a `Mono` publisher because we want to return a single instance, and we are using the `ResponseEntity` object to enable us to return HTTP status 404 in case the book doesn't exist in our application domain. This endpoint is also useful to show how WebFlux is compatible with a traditional HTTP implementation.

##### GET /booksWithDelay

For this endpoint we do something slightly different from the GET /books endpoint: we add a delay time between each item to simulate processing time. This is done through the method call `delayElements(Duration.ofMillis(1000))`. The publisher will wait for 1 second before addressing each item in the stream. Notice that the media type we produce is also different. We are producing an `application/stream+json` media instead of a simple JSON. That is useful for telling our client that we are returning a stream instead of a regular response entity. 

##### Testing

The traditional web client implementation for consuming REST APIs in Spring is the `RestTemplate` class. With the new reactive framework, we also get a reactive REST client implementation: the `WebClient` class. For writing our integration tests, we are going to auto-inject the implementation of `WebClient` for testing purposes, which is `WebTestClient`. Its fluent interface allows us to do method chaining and assert the results in a more declarative way. Observe that all the pre- and post-test operations in the DB are using the `block()` method to avoid synchronization problems. 

 

Let's explore the `/booksWithDelay` endpoint with curl. First, we need to build our API. From inside the project directory, execute:

`$ gradle build`

When the previous command is finished, start up the web server with:

`$ gradle bootRun`

Check in the console to see when the application is done starting. After it's done, we can start sending requests to our endpoints. Let's create two books in the DB:

`$ curl -X POST http://localhost:8080/books  -H 'content-type: application/json' -d '{ "isbn" : "978-0451518651", "title" : "1984", "publicationDate" : "1949-06-08"}'`

`$ curl -X POST http://localhost:8080/books -H 'content-type: application/json' -d '{"isbn" : " ‎0-330-25864-8", "title" : "The Hitchhiker'\''s Guide to the Galaxy", "publicationDate" : "1979-10-12"}'`

 

Now, let's retrieve them by using the `GET /booksWithDelay`:

`$ curl -X GET http://localhost:8080/booksWithDelay`

`{"isbn":"978-0451518651","title":"1984","publicationDate":"1949-06-08"}`

`{"isbn":" ‎0-330-25864-8","title":"The Hitchhiker's Guide to the Galaxy","publicationDate":"1979-10-12"}`

You should notice that the books are being provided with a 1s delay between each other. That's because we added that delay on purpose to illustrate the reactive concept. We could use subscribers to this publisher to process information as it becomes available rather than having to wait for all items to become available.

##### Final Considerations

Now that we've learned a little more about reactive programming with Spring, it's important to make a couple closing remarks. If you try to debug a functional reactive API, you are going to find out that debugging is much harder when you use functional style. That's something to account for, depending on how complex your application is. Also, keep in mind that if you already use Spring MVC, there's no need to completely switch to WebFlux. Both styles work together without any problems, so you can build reactive controllers that coexist with your MVC controllers. I hope you have enjoyed learning something new!

##### References:

[WebFlux Framework, Part 5. The Web](https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html)

[Web on Reactive Stack](https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html)

[Spring Framework Guru](https://springframework.guru/spring-data-mongodb-with-reactive-mongodb/)

 

 

 

 

 

 

 

 

 

 

---

### Author

# Leonardo Silva

 Leonardo Silva is a Java Consultant at Avenue Code. He has been working with Java applications development for 4 years. He holds a Bachelor degree in Computer Science from Unicamp.

---

### Related Posts

### Asymmetric Cryptography

[READ MORE](https://blog.avenuecode.com/asymmetric-cryptography?hsLang=en-us)

### Improving the developer experience when documenting

[READ MORE](https://blog.avenuecode.com/improving-the-developer-experience?hsLang=en-us)

### How to Run Rust from Python

[READ MORE](https://blog.avenuecode.com/how-to-run-rust-from-python?hsLang=en-us)

### How to Create a Tic-Tac-Toe Board Using React.js

[READ MORE](https://blog.avenuecode.com/how-to-create-a-tic-tac-toe-board-using-react.js?hsLang=en-us)

### Leave a Comment!

### Avenue Code Social

[![Facebook Icon](https://blog.avenuecode.com/hubfs/Images/Blog/facebook.png?t=1486470796564)](https://www.facebook.com/avenuecode)

[![Twitter Icon](https://blog.avenuecode.com/hubfs/Images/Blog/twitter.png?t=1486470796842)](https://twitter.com/AvenueCode)

[![LinkedIn Icon](https://blog.avenuecode.com/hubfs/Images/Blog/linkedin.png?t=1486470796556)](https://www.linkedin.com/company/avenue-code)

### Newsletter

Want to stay on top of all tips and news from Avenue Code?

### Popular Snippets

![Primary Logo AvenueCode Inverted.png](https://blog.avenuecode.com/hs-fs/hubfs/Images/Logos/Primary%20Logo%20AvenueCode%20Inverted.png?width=1104&name=Primary%20Logo%20AvenueCode%20Inverted.png "Primary Logo AvenueCode Inverted.png")

### About Us

- [Who We Are](https://www.avenuecode.com/who-we-are)
- [What We Do](https://www.avenuecode.com/what-we-do)
- [Portfolio](https://www.avenuecode.com/portfolio)
- [Partners](https://www.avenuecode.com/partners)
- [News](https://www.avenuecode.com/news)
- [Events](https://www.avenuecode.com/events)
- [Blog](https://blog.avenuecode.com/)
- [Contact](https://www.avenuecode.com/contact)

### Our Offices

San Francisco

[+1 415 766 4178](tel:+553125161448) [ac.inquiries@avenuecode.com](mailto:brazil.info@avenuecode.com)

Belo Horizonte

[+55 31 2516 1448](tel:+553125161448) [brazil.info@avenuecode.com](mailto:brazil.info@avenuecode.com)

São Paulo

[+55 11 3205 3232](tel:+553125161448) [brazil.info@avenuecode.com](mailto:brazil.info@avenuecode.com)

### We're Hiring!

- [Belo Horizonte](https://www.avenuecode.com/who-we-are)
- [New York](https://www.avenuecode.com/what-we-do)
- [San Francisco](https://www.avenuecode.com/portfolio)
- [São Paulo](https://www.avenuecode.com/partners)

---

©2015 - 2017 Avenue Code

[![Facebook Icon](https://blog.avenuecode.com/hubfs/Images/Icons/facebook-2.png)](https://www.facebook.com/avenuecode) [![Twitter Icon](https://blog.avenuecode.com/hubfs/Images/Icons/twitter-2.png)](https://twitter.com/AvenueCode) [![LinkedIn Icon](https://blog.avenuecode.com/hubfs/Images/Icons/linkedin-2.png)](https://www.linkedin.com/company/avenue-code) [![Glassdoor Icon](https://blog.avenuecode.com/hubfs/Images/Icons/glassdoor-icon-1.png)](https://www.glassdoor.com/Overview/Working-at-Avenue-Code-EI_IE456173.11,22.htm) [![YouTube Icon](https://blog.avenuecode.com/hubfs/Images/Icons/youtube-2.png)](https://www.youtube.com/user/AvenueCodePlay)

Please enable JavaScript to view the [comments powered by Disqus.](http://disqus.com/?ref_noscript)

© 2026 Avenue Code

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Leonardo Silva",
    "url" : "https://blog.avenuecode.com/author/leonardo-silva"
  },
  "dateModified" : "2018-10-24T20:00:05.139Z",
  "datePublished" : "2018-10-24T20:00:00.000Z",
  "headline" : "Spring WebFlux: A Quick Start",
  "image" : [ "https://blog.avenuecode.com/hubfs/spring-featured-image.png" ],
  "mainEntityOfPage" : {
    "@id" : "https://blog.avenuecode.com/spring-webflux-a-quick-start",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://blog.avenuecode.com/hubfs/Avenue%20Code%20New%20Logos%20-%202023/Avenue%20Code-primary%20versions_LOGO%20HORIZONTAL%20group%201-7.png"
    },
    "name" : "Avenue Code"
  }
}
```