Reactive Programming with Quarkus

As you know, Quarkus has built-in Jaxrs support with RESTEasy when you are creating a Quarkus application.

Image for post
Image for post

Most of developers are familiar with the imperative programming methods like this.

In Quarkus, you can use ReactiveStreams Publisher as return type.

Besides the standard ReactiveStreams APIs, you can also use Java 8 CompletableFuture, RxJava 2, and SmallRye Munity.

For the database connecting to the underlay database, you can switch to the Reactive PostgresSQL Client or Reactive MySQL Client.

Currently Hibernate core and JPA do not support ReactiveStreams APIs, but there is a new sub project under Hibernate which is trying to do this problem, see Hibernate RX.

In this post, we will refactor the sample used in the former post, and reimplement it by using the reactive features in Quarkus.

We will start with SmallRye Munity which may be new to developers including me, and then we will explore the Java 8 CompletableFuture and RxJava 2.

First of all, create a Quarkus project quickly using Quarkus coding if you want to work on a new project, and add Resteasy Munity, Reactive Pg Client to dependencies.

Or running the following command to add required Quarkus extensions to the existing Quarkus project.

SmallRye Munity implements the ReactiveStreams specification, and provides two conventional classes — Uni and Multi.

  • Uni — handle stream of 0..1 items
  • Multi — handle stream of 0..n items (potentially unbounded)

The Reactive Pg Client is derived from Vertx Reactive Pg Client, with the help of Quarkus, you can configure database connection in the application.properties directly, and inject the reactive Postgres Client PgPool bean in your codes.

Let’s have a look at the Post class, there is no extra annotations on this version.

And move to the Repository class, which is use for performing CRUD operations on table posts.

In the above codes,

The PgPool is imported from package io.vertx.mutiny.pgclient, there are several variants for different underlay implementations.

The preparedQuaery method accepts a second parameter and bind them to the SQL statements.

The RowSet::rowCount return the number of the affected rows when performing a update or deletion queries.

In the findAll and find methods, use map to transform a RowSet to our custom Post instance.

Now let’s explore the changes in PostResource.

Yes, with the help of resteasy-munity extension, you can return Uni or Multi types in the Jaxrs resources.

Let’s take a closer look at the getPostById method in the above PostResource, it looks a little ugly. In our PostRepository class, the findById return a Uni, when there is a Post found return back a Uni<Post>, else there is a null in the Uni stream. So in getPostById we have to filter out it in the main flow and handle the null case in the onItem().ifNull(). For my opinion, it is a little tedious, currently there is no replacement of switchIfEmpty like methods in Munity.

To make it more understandable, use a custom exception in PostRepository like this.

And in the PostResource class, handle this exception in the onFailter event.

In the application.properties file, configure the datasource like this.

Similar with the Jdbc datasource, but here it use the prefix vertx-reactive: in the connection url.

Like the former post, we will use a DataInitializer bean to insert some sample data at the application startup.

When the Quarkus application is started, it will raise an StartupEvent, the DataInitializer observes it and insert the data as expected.

To start a Postgres server, simply use the docker-compose file provided in my repos to serve a Postgres server in docker.

It uses the predefined initial scripts to prepare the tables used in our sample at the startup stage.

Now, let’s start up our application.

Execute the following command in the root folder of the project.

Open a terminal, and try to access the sample API endpoints using the curl command.

Awesome, it works as expected.

The complete codes can be found here.

As mentioned, in a Quarkus application, you can also use Java 8 CompletableFuture or RxJava 2 APIs if you prefer them.

Let’s have a look the version of using Java 8 CompletableFuture.

The Repository class.

Note : The PgPool here is from package io.vertx.axle.pgclient.

The PostResource class.

The complete codes of Java 8 version can be found here.

Let’s take a quick look at the RxJava 2 version.

The PostRepository class.

Note, in this class, the PgPool is from package io.vertx.reactivex.sqlclient.

The PostResource class.

The complete codes of the RxJava 2 version can be found here.

Written by

Self-employed technical consultant, solution architect and full-stack developer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store