Quarkus Tutorial

How to set up a REST API using Quarkus.io

How to set up a REST API using Quarkus.io


Quarkus Tutorial
(série de 3 partes)

How to set up a REST API using Quarkus.io
Configure JPA on Quarkus.io
Using Bean Validation on 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>

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>

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

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

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

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!";
    }
}

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();
    }
}

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);
    }
}

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

Quarkus Tutorial
(série de 3 partes)

How to set up a REST API using Quarkus.io
Configure JPA on Quarkus.io
Using Bean Validation on Quarkus.io
Originally published November 09, 2020