
Introduction
On March seventh, RedHat (soon to be IBM) introduces a new framework — . According to the developers, this framework is based on GraalVM and OpenJDK HotSpot and is intended for Kubernetes. The Quarkus stack includes: JPA/Hibernate, JAX-RS/RESTEasy, Eclipse Vert.x, Netty, Apache Camel, Kafka, Prometheus, and others.
The goal of its creation is to make Java the leading platform for deployment in Kubernetes and development of serverless applications, providing developers with a unified approach for programming in both reactive and imperative styles.
If we look at the classification of frameworks, Quarkus falls somewhere between 'Aggregators/Code Generators' and 'High-level fullstack frameworks'. It is more than just an aggregator but does not quite reach full-stack status since it is tailored for backend development.
Very high application startup speed and low memory consumption are promised. Here are the data from the developer’s website:
Time from start to first response (s):
Configuration
REST
REST+JPA
Quarkus+GraalVM
0.014
0.055
Quarkus+OpenJDK
0.75
2.5
Traditional Cloud Native Stack*
4.3
9.5
Memory consumption (Mb):
Configuration
REST
REST+JPA
Quarkus+GraalVM
13
35
Quarkus+OpenJDK
74
130
Traditional Cloud Native Stack*
140
218
Impressive, isn't it?
*I couldn't find any information about this technology stack, one might assume it's some kind of Spring Boot with additional features..
Hello World!
The simplest application written in Quarkus would look like this:
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}This is literally one class and it's enough! You can run the application using Maven in development mode:
mvn compile quarkus:dev
…
$ curl http://localhost:8080/hello
helloThe difference from a regular application is that there is no Application class! Quarkus supports hot reload, allowing you to change the application without restarting it, making development even faster.
What's next? You can add a service to the controller using the annotation . The service code:
@ApplicationScoped
public class GreetingService {
public String greeting(String name) {
return "Hello " + name + "!";
}
}Controller:
@Path("/hello")
public class GreetingResource {
@Inject
GreetingService service;
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/{name}")
public String greeting(@PathParam("name") String name) {
return service.greeting(name);
}
}$ curl http://localhost:8080/hello/developer
Hello developer!Note that Quarkus uses standard annotations from familiar frameworks — CDI and JAX-RS. There's nothing new to learn if you have worked with CDI and JAX-RS before, of course.
Working with the database
Hibernate and standard JPA annotations are used for entities. As with REST controllers, a minimal amount of code is required. It is sufficient to specify dependencies in the build file and place the annotations. @Entity and configure the datasource in application.properties.
That's all. No sessionFactory, persistence.xml, or other service files are needed. We only write the code that is necessary. However, if necessary, a persistence.xml file can be created to configure the ORM layer more finely.
Quarkus supports caching of entities, collections for one-to-many relationships, as well as queries. At first glance, it looks great, but this is local caching for a single Kubernetes node. That is, caches of different nodes are not synchronized with each other. I hope this is temporary.
Asynchronous code execution
As mentioned above, Quarkus also supports reactive programming style. The code of the previous application can be rewritten in another form.
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/{name}")
public CompletionStage greeting(@PathParam("name") String name) {
return CompletableFuture.supplyAsync(() -> {
return "Hello " + name + "!";
});
}
}Asynchronous code can also be moved to a service, and the result will be the same.
Testing
Tests for Quarkus applications can be written using JUnit4 or JUnit5. Below is an example test for the endpoint, written using RestAssured, but another framework can also be used:
@QuarkusTest
public class GreetingResourceTest {
@Test
public void testGreetingEndpoint() {
String uuid = UUID.randomUUID().toString();
given()
.pathParam("name", uuid)
.when().get("/hello/{name}")
.then()
.statusCode(200)
.body(is("Hello " + uuid + "!"));
}
}The @QuarkusTest annotation instructs to start the application before running the tests. Otherwise, it is familiar code for all developers.
Platform-dependent application
Since Quarkus is tightly integrated with GraalVM, it is indeed possible to generate platform-dependent code. To do this, you need to install GraalVM and set the GRAALVM_HOME environment variable. Then and specify it when building the application:
mvn package -PnativeInterestingly, the generated application can be tested. This is important because the execution of native code may differ from execution on the JVM. The @SubstrateTest annotation runs platform-dependent code of the application. Reusing existing test code can be accomplished through inheritance; thus, the code for testing a platform-dependent application would look like this:
@SubstrateTest
public class GreetingResourceIT extends GreetingResourceTest {
}The generated image can be packaged in Docker and run in Kubernetes or OpenShift, as detailed in .
Toolset
The Quarkus framework can be used with Maven and Gradle. Maven is fully supported, unlike Gradle. Unfortunately, at present, Gradle does not support the generation of an empty project; detailed information can be found on the website. .
Extensions
Quarkus is an extensible framework. Currently, there are about , which add various functionalities — from supporting and to logging and publishing metrics for running services. There is already an extension to support writing applications in Kotlin, in addition to Java.
Conclusion
In my opinion, Quarkus is very much in line with current trends. Backend development is becoming simpler and simpler, and this framework further simplifies and accelerates service development, adding native support for Docker and Kubernetes. A huge plus is the built-in support for GraalVM and the generation of platform-dependent images, allowing services to start up really quickly and occupy little memory. This is crucial in our time of widespread interest in microservices and serverless architecture.
The official website is — . Project examples for quick start are already available on .
Source: habr.com
