Developing Reactive Microservices With Spring Data and Distributed SQL
In this article, we will walk you through the basics of getting started with a fully reactive tech stack, from web controllers to database calls.
Join the DZone community and get the full member experience.Join For Free
In 2016 in the keynote presentation of Spring One Platform, Juergen Hoeller announced Spring WebFlux, one of the most highly anticipated projects being worked on by the Spring Team due to the performance gains that reactive streams promised for web controllers. Subsequently, with Spring Framework 5.0, Spring Reactive MVC went GA along with the release of WebFlux API, making the reactive stream-based web controller mainstream.
Fast-forward to 2020, Spring WebFlux MVC has gained wide adoption in cloud-native applications, where developers strive for high throughput and low latency microservices. Clearly there has been a shift towards the reactive programming model, now that many of the database providers support reactive drivers where traditional blocking database calls are replaced by async and non-blocking back pressure aware data access.
In this article, we will walk you through the basics of getting started with a fully reactive tech stack, from web controllers to database calls. We will build a Spring microservice using Spring WebFlux, Spring Data Reactive Repositories, and YugabyteDB, which supports reactive drivers for CRUD operations.
What’s YugabyteDB? It is an open-source, high-performance distributed SQL database built on a scalable and fault-tolerant design inspired by Google Spanner.
The Technology Stack to Build a Spring Microservices Application
By following this tutorial, we will build a Spring microservices application exposing the reactive REST API for performing CRUD operations against YugabyteDB. This sample application uses the following tech stack:
- Spring WebFlux – Support for reactive MVC controllers and REST controllers.
- Spring Data reactive for Apache Cassandra – Reactive repositories support for YugabyteDB.
- Yugabyte Cloud Query Language (YCQL) – A SQL-based, flexible-schema API that supports distributed transactions, strongly consistent secondary indexes, and a native JSON column type. YCQL is compatible with the query dialect of Apache Cassandra and works natively with Apache Cassandra reactive drivers.
The Git repo for the sample application is here.
Start the YugabyteDB cluster using the following command from YugabyteDB installation directory:
This will start a 3-node local cluster with a replication factor (RF) 3. The flag
cql_nodelist_refresh_interval_secs configures how often the drivers will get notified of cluster topology changes and the following flag
tserver_unresponsive_timeout_ms is for the master to mark a node as dead after it stops responding (heartbeats) for 10 seconds.
Note: Here are the complete instructions for installing YugabyteDB on your local Mac laptop.
Project Initialization and Dependency Configuration
Create a new Spring Boot project using Spring Initializr and add the following dependencies required for the sample application:
- Spring Reactive Web
- Spring Data Reactive for Apache Cassandra
On reviewing the
pom.xml of the project, you will see the following reactive dependencies:
Reactive Repository Configuration
Spring Boot auto reconfiguration initializes the Cassandra datasource on startup, all we have to do is to specify the YugabyteDB connection information in
application.properties as shown below:
Once we have the data source configuration applied, let’s go ahead and review the reactive repositories required for the sample application.
The sample application contains the
product domain object, for which we will be creating reactive repositories for performing CRUD operations. The domain object should have the
@Id annotations of Spring Data Cassandra:
Now let’s implement a reactive repository for the
product domain object:
ReactiveCassandraRepository interface enables reactive APIs for all the common operations Spring Data supports like
deleteByID(). As you might expect, these API calls will return reactive types, either
flux<> based on the result of the API call.
Reactive REST Controller and Data Access
As we saw from the previous section, all boilerplate code for data source creation and implementing the data access code is provided by the Spring Framework. Let us now use the product repository in our reactive REST controller.
That’s it! Controller methods that are using the repository APIs are also returning reactive types, which makes the overall interaction asynchronous, from serving the HTTP request to database calls, giving applications performance benefits of having a fully reactive programming model.
As cloud-native applications shift towards a non-blocking programming model, application developers can quickly start prototyping using Spring abstractions for reactive programming. Coupling that with distributed cloud-native databases like YugabyteDB, which supports reactive drivers for data access, will result in highly scalable and performant applications.
Published at DZone with permission of Nikhil Chandrappa. See the original article here.
Opinions expressed by DZone contributors are their own.