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.
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.
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:
- Add the dependencies
- Configure the package
- 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:
- Create REST API
- Add JSON Support
- Add Reactive Support
For that we will need the following dependencies:
-
io.quarkus:io.quarkus
for creating the REST API -
io.quarkus:quarkus-resteasy-jsonb
for adding JSON serializer to REST API -
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
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
In the first example, we create a minimal REST API using Quarkus and JAX-RS.
2. Configure JPA Jakarta Persistence
In the second example, we add the persistence layer for our REST API.
3. Configure Jakarta Bean Validation
In the third example, we add the validation to all layers of our REST API.
Top comments (0)