DEV Community

Cover image for How to set up a REST API using Quarkus.io
Victor Osório
Victor Osório

Posted on • Updated on • Originally published at vepo.github.io

How to set up a REST API using Quarkus.io

Why Quarkus is a good choice?

Quarkus is one of the best frameworks for Java! First, there was the Wildfly, that as an experiment became a microservices focus project called Wildfly Swarm. Then Wildfly Swarm was renamed to Thorntail. The main purpose of Thorntail was to build a Jakarta EE implementation build for microservices. But there was some pitfall that needed a full rewrite for the code. So this is Quarkus, a light implementation, ready for microservices and it has native support to GraalVM.

Quarkus metrics

So Quarkus is based on lessons learned from previous development. Based on these lessons I believe this will be a better framework, easy to use and fast on execution.

Thorntail icon

Mangling artifacts is dangerous
When you mangle and repackage a user’s artifacts and dependencies, it can many times go awry.

Don’t replace Maven
Let Maven (or Gradle) handle the entirety of pulling dependencies. We cannot predict the topology of someone’s repository managers, proxies and network.

Don’t get complicated with uberjars
The more complex our uberjar layout is, the harder it is to support Gradle or other non-Maven build systems.

Classpaths are tricky
If different codepaths are required for executing from Maven, an IDE, a unit-test, and during production, you will have a bad time.

Don’t insist on uberjars
For Linux containers, people want layers that cleanly separate application code from runtime support code.

Testability is important
A slow test is a test that is never willingly executed. PRs take forever to validate. Users like to be able to test their own code quickly and iteratively.

Easily extensible means ecosystem
If it’s entirely too difficult to extend the platform, the ecosystem will not grow. New integrations should be simple.

Related: Core things should not be any more first-class than community contributions
For instance, auto-detection in WildFly Swarm only worked with core fractions; user-provided wouldn’t auto-detect.

Ensure the public-vs-private API guarantees are clear.
Intertwingly code (and javadocs) make finding the delineation between public API and private implementations difficult.

Allow BYO components
We don’t want to decide all of the implementations, and certainly not versions, of random components we support.

Be a framework, not a platform
Frameworks are easier to integrate into an existing app; a platform becomes the target with (generally too many) constraints.

Maintain tests & documentation
Ensure the definition of "done" includes both tests and documentation.

Productization complexity
The greater divergence between community and product, the more effort is required for productization. Complicating any process to automate productization from community.

BOM complexity
Related to productization as well, but of itself having a handful of BOMs made life confusing for us and for users. There were often times where fractions would be "Unstable" or "Experimental" for months with no real reason other than we forgot to update it.

Configure Quarkus

The first question we need to answer on a tutorial is: To build a project using Quarkus, what do you need?

For Quarkus we need:

  1. Add the dependencies
  2. Configure the package
  3. Starting coding

1. Configure the dependencies

As Quarkus is a Jakarta EE, we will use the Jakarta EE annotations on the code. But, for the pom.xml we should point to Quarkus dependencies because quarkus has native support for GraalVM.

First we need add all dependencies to Quarkus, this can be done using dependencyManagement:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-universe-bom</artifactId>
            <version>1.9.2.Final</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
Enter fullscreen mode Exit fullscreen mode

The for that project we will need:

  1. Create REST API
  2. Add JSON Support
  3. Add Reactive Support

For that we will need the following dependencies:

  1. io.quarkus:io.quarkus for creating the REST API
  2. io.quarkus:quarkus-resteasy-jsonb for adding JSON serializer to REST API
  3. io.quarkus:quarkus-resteasy-mutiny for adding reactive support for REST API

2. Configuring the build

The next step we should configure Quarkus build. As we know, Quarkus creates a fat jar with all dependencies.

To enable the Quarkus builder on Maven, just add the following plugin:

<plugin>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-maven-plugin</artifactId>
    <version>1.9.2.Final</version>
    <executions>
        <execution>
            <goals>
                <goal>generate-code</goal>
                <goal>generate-code-tests</goal>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Enter fullscreen mode Exit fullscreen mode

In this example, I'm compiling as Java 11, but I'm using Java 15 to test. It will work for any version of Java newer than 11. If you need to execute it on Java 8, just change the compiler options.

We can make the build just executing:

mvn clean package
Enter fullscreen mode Exit fullscreen mode

This will create two jars inside the target folder, the one terminating with -runner.jar can be executed with no dependencies.

$ java -jar target\quarkus-tutorial-runner.jar
__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2020-11-09 11:16:53,416 INFO  [io.quarkus] (main) quarkus-tutorial 0.0.1-SNAPSHOT on JVM (powered by Quarkus 1.9.2.Final) started in 4.706s. Listening on: http://0.0.0.0:8080
2020-11-09 11:16:53,470 INFO  [io.quarkus] (main) Profile prod activated.
2020-11-09 11:16:53,475 INFO  [io.quarkus] (main) Installed features: [cdi, mutiny, resteasy, resteasy-jsonb, resteasy-mutiny, smallrye-context-propagation]
2020-11-09 11:16:58,790 INFO  [io.quarkus] (Shutdown thread) quarkus-tutorial stopped in 0.024s
Enter fullscreen mode Exit fullscreen mode

This is the way we should execute for production environments, for development we can use Quarkus Maven plugin. It already does the deploy of any change on the running server:

mvn quarkus:dev
Enter fullscreen mode Exit fullscreen mode

3. Adding the REST API Endpoint

The latest step for creating an API is creating the code that will handle the requests. Using JAX-RS is easy, just create a class and add the annotations.

The most simple example is:

@Path("/hello")
@ApplicationScoped
public class HelloEndpoint {
    @GET
    public String sayHello() {
        return "Hello World!";
    }
}
Enter fullscreen mode Exit fullscreen mode

JAX-RS automatically generate a JSON representation for any object returned by this method, you have just to inform the MIME Type.

@Path("/hello")
@ApplicationScoped
public class HelloEndpoint {
    private HelloResponse generateResponse() {
        HelloResponse response = new HelloResponse();
        response.setCode(new Random().nextInt());
        response.setMessage("Hello World!");
        return response;
    }

    @GET
    @Path("/json")
    @Produces(MediaType.APPLICATION_JSON)
    public HelloResponse sayHelloWithJson() {
        return generateResponse();
    }
}
Enter fullscreen mode Exit fullscreen mode

Quarkus also have support for reactive programming. For JAX-RS, you have just to return a Uni or a CompletableFuture.

@Path("/hello")
@ApplicationScoped
public class HelloEndpoint {
    private HelloResponse generateResponse() {
        HelloResponse response = new HelloResponse();
        response.setCode(new Random().nextInt());
        response.setMessage("Hello World!");
        return response;
    }

    @GET
    @Path("/json/reactive")
    @Produces(MediaType.APPLICATION_JSON)
    public Uni<HelloResponse> sayHelloWithJsonReactively() {
        return Uni.createFrom().item(this::generateResponse);
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

With Quarkus you can build quickly a REST API using JAX-RS. As JAX-RS is a Jakarta EE specification, you can migrate your code with few changes to another existing implementation, but Quarkus is the lighter implementation.

Quarkus is a good choice!

You can find all examples on github.com/vepo/quarkus-tutorial

GitHub logo vepo / quarkus-tutorial

This is a series of blog posts where I will create a tutorial of Quakus.io.

Quarkus Tutorial

Steps

1. Create a REST API

More information

In the first example, we create a minimal REST API using Quarkus and JAX-RS.

2. Configure JPA Jakarta Persistence

More information

In the second example, we add the persistence layer for our REST API.

3. Configure Jakarta Bean Validation

More information

In the third example, we add the validation to all layers of our REST API.

Cover Image

Oldest comments (0)