Building a REST API With Quarkus
Focusing on fast start-up times and low memory usage making it more suitable to run within container orchestration platforms like Kubernetes.
Join the DZone community and get the full member experience.Join For Free
Quarkus is a Java framework designed to run within containers. Focusing on fast start-up times and low memory usage making it more suitable to run within container orchestration platforms like Kubernetes.
I wanted to write about Quarkus for a while now, and have finally found the time to do so.
The content of this post will focus on writing a simple REST API using Quarkus. I will not explain how Quarkus works, because, well, I haven’t put the time in yet to do so correctly. Hopefully, I can rectify this in future posts. Therefore, if you want more information about Quarkus, I suggest you browse their docs. So far, I have found them detailed, well written, and I will personally continue using them while I explore Quarkus further.
Creating a Project
Quarkus provides a maven command to bootstrap your projects, for example (the below works for Linux and MacOS, see the Quarkus - Getting started guide for more information):
This generates a basic project with a HTTP endpoint in
PersonResource with the path
hello, along with several resources to build and run your application. In fact, you should have enough at this point to run the generated code, both locally and inside a container.
pom.xml is included that contains the required dependencies. You will need to add to this if you want to write anything past a hello world example.
By running (from inside your project):
You can see the Quarkus dependencies/extensions available to your project.
Then you can add an extension using a command like the one below:
./mvnw quarkus:add-extension -Dextensions="hibernate-validator"
The other option is to add it manually as I would typically do when sorting out my dependencies. Just thought I’d mention the
add-extension command as I hadn’t actually come across this method of dependency management when using Maven.
I keep mentioning Maven, but there is no reason you can’t using something else, such as Gradle.
Quarkus Uses JAX-RS for its REST Capabilities
Quarkus follows the JAX-RS specification with Resteasy providing its implementation. If you have worked with Java for a reasonable time, you have probably seen or written code that follows the JAX-RS spec. And if you haven’t, you probably will at some point. I haven’t needed to use it before myself (I tend to use Spring when in Java land) so it is reasonably new to me. Anyway, in general, you can implement most of a simple REST API by relying on a few annotations.
Quarkus Uses CDI Beans for Dependency Injection
Quarkus’ dependency solution is based on the CDI (Context and Dependency injection) specification. It should be noted that Quarkus does not provide a full CDI implementation, meaning that there will be limitations compared to other frameworks that you might have used. More information can be found in Quarkus’ CDI reference and their Introduction to CDI.
Implementing a REST API
I have put together an example REST API that manages people. I mean, the purpose of the API doesn’t really matter, it’s just an example after all. Here comes a long chunk of code:
As I mentioned earlier, Quarkus uses Resteasy as its JAX-RS implementation. All of the annotations in this class are related to JAX-RS. Let’s have a quick look at one of the functions:
@GETspecifies that the method handles GET HTTP requests.
@PathParamwork together to take the HTTP path variable
idand use it as the endpoint’s input
@Produces(MediaType.APPLICATION_JSON)denotes the type of data that the endpoint returns as JSON
That’s enough about annotations. The rest of the method consists of finding the
Person matching the input
id and returning it to whatever called the endpoint. Instead of returning a
Person directly, you could use a
Response object, but I wanted to keep it simple and easier to read.
You have a choice between using JSON-B or Jackson for your serialization. Personally, I tend to use Jackson so I went ahead and plugged it in. You will need to add the extension for whichever you choose:
Or via the command:
./mvnw quarkus:add-extension -Dextensions="resteasy-jackson"
Replace “jackson” with “jsonb” to switch over to JSON-B
Connecting to a Database Using JDBC
This API is not going to do anything useful if it isn’t persisting data somewhere.
Quarkus provides JDBC implementations for connecting to databases. I chose to use Postgres for this project’s database, but you can obviously use whatever suits your needs. More information can be found in Quarkus’ data source documentation.
The first thing you need to add to connect to a database, is a JDBC driver dependency:
You could also run:
./mvnw quarkus:add-extension -Dextensions="jdbc-postgresql"
Then add properties specifying the connection type and the details (to your
You don’t want to directly manage the database connections yourself (I assume so anyway).
Agroal is a modern, light weight connection pool implementation designed for very high performance and scalability, and features first class integration with the other components in Quarkus, such as security, transaction management components, health metrics.
What this means for you:
- Add the Agroal extension to your dependencies:
./mvnw quarkus:add-extension -Dextensions="agroal"
- Inject the
DataSourcethat it initialises into your code (either directly via
AgroalDataSourceor using the
Creating a Repository
Once you have sorted out the data source connection and have enabled connection pooling, you can now start writing queries. Below is a slimmed-down version of the
PersonRepository since its using raw JDBC meaning that the code is quite lengthy and duplicated between functions:
The main take away of this snippet is the usage of the
DataSource which Agroal provided the implementation for. You can inject it into your components after only needing to include the dependencies for a JDBC driver and Agroal itself. In regards to the JDBC code, more information on general JDBC usage can be found here.
Running the Application
To run a Quarkus application, execute:
./mvnw compile quarkus:dev
This runs the application in dev mode, which enables hot-reloading. Making your development experience a bit smoother. Although, I did find it hard to break the habit of restarting my application after every code change…
To run your application for real, or non dev mode, you need to build the application’s jar and run it. You can do this using:
java -jar target/quarkus-1.0-SNAPSHOT-runner.jar
./mvnw packageplaces the generated jar in the target directory
If you used the command I showed at the beginning of this post to generate your project, you would have a
README.md containing all this information. Including how to construct a native executable and running your Quarkus application within a container. I will cover some of this in future blog posts.
You should now have a good idea on how to write a REST API using Quarkus. Like most other frameworks, you can leverage dependencies to quickly and effectively build your applications. Quarkus allows you to do the same. That can be seen by the number of times I told you to add a new dependency!
Bringing the focus back onto what Quarkus provides you, remember it’s a framework specialising on fast start-up times and low memory usage. I purposely left further discussion on these factors out to allow the post to focus on building an application using Quarkus, which is pretty much the same as building any REST application that uses JAX-RS. So when developers/engineers, like you, search for how to build a REST API using Quarkus, they can see that it is nothing alien. I will cover the benefits of using Quarkus in future content
I have left parts out to not distract from the main content, but you can find all of the code I used to create the example in my GitHub repository.
Published at DZone with permission of Dan Newton, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.