Quarkus 5
Quarkus 5
Continuous testing will need to be re-enabled after making a change to the project’s
dependencies. On the terminal, press the r key to resume continuous testing.
@InjectMock
GreetingService greetingService;
Replace the contents of the testHelloEndpoint() method with the contents from Note: Similarly, the
Listing 2.13 and save the changes. @InjectSpy annotation
from Quarkus spies on a
Listing 2.13: GreetingResourceTest.java.
bean just like the @SpyBean
@QuarkusTest annotation provided by the
public class GreetingResourceTest { Spring Boot Test framework.
@InjectMock
GreetingService greetingService;
@Test
public void testHelloEndpoint() {
Mockito.when(this.greetingService.getGreeting())
.thenReturn(“Hello Quarkus”);
given()
.when().get(“/hello-resteasy”)
.then()
.body(is(“Hello Quarkus”));
Mockito.verify(this.greetingService).getGreeting();
Mockito.verifyNoMoreInteractions(this.greetingService);
}
}
The Mockito.when(this.greetingService.getGreeting()).thenRe-
turn(“Hello Quarkus”); statement says that when the getGreeting() method
is called on the GreetingService bean, the call returns the value Hello Quarkus.
GreetingService.getGreeting() method was
called exactly once, and no other methods were called on the GreetingService class.
Return to the terminal and notice that Quarkus automatically ran the test successfully.
--
All 2 tests are passing (0 skipped), 1 tests were run in 697ms.
Feel free to try out the continuous testing a bit more by making changes to the applica-
tion source code. Quarkus will automatically rerun tests affected by changes made.
Return to the terminal where the ./mvnw quarkus:dev command is running and ter-
minate Dev Mode.
native image. The native image should also be tested as part of the build process.
However, keep in mind that the tests do not run within the native image; they run in
the JVM. The native application image runs in a separate process, and a native image
test interacts with the application as an external client. This separation prohibits in-
jecting or mocking beans in a native image test. Instead, a native image test typically
interacts with the application via HTTP, messaging, or other communication channels,
just like any other external client to the application. Additionally, by default, the native
image runs the prod quarkus.
property in src/main/resources/application.
properties.
To create a native image test, create a new test class and extend an existing JVM
test annotated with @QuarkusTest, placing the @NativeImageTest annotation on
it. As mentioned previously, if the base test class injects or mocks beans, those
tests need to be excluded from the native image test by annotating test methods
with the @DisabledOnNativeImage annotation. The native image test class can then
add additional test methods.
This command will compile the application, run the regular tests, and build a native im-
age. It may take a few minutes for the native image build to complete. Once complet-
ed, the native image starts and the native image tests run within the JVM. The output
should show something similar to the following, indicating successful native image test
execution:
Native image tests aren’t required to extend another test class. The code.quarkus.
io generator uses this convention purely for convenience. There may be tests in the
inheritance. You could remove the extends GreetingResourceTest clause from the
NativeGreetingResourceIT class and the native image tests would run successfully.
References
[2.1] “Quarkus Tools for Visual Studio Code”: https://marketplace.visualstudio.com/
items?itemName=redhat.vscode-quarkus
[2.2] “JetBrains IntelliJ IDEA Ultimate Edition Quarkus Tooling”:
https://www.jetbrains.com/help/idea/quarkus.html
[2.3] “Quarkus Tools for IntelliJ plugin”:
https://plugins.jetbrains.com/plugin/13234-quarkus-tools
[2.4] “Quarkus Tools JBoss Tools”: https://tools.jboss.org/features/quarkus.html
[2.5] “Quarkus Tools on Eclipse Marketplace”:
https://marketplace.eclipse.org/content/quarkus-tools
[2.6] “Spring Boot Starters”: https://docs.spring.io/spring-boot/docs/current/refer-
ence/htmlsingle/#using-boot-starter
[2.7] “Quarkiverse”: https://github.com/quarkiverse/quarkiverse/wiki
[2.8] “Quarkus Extension for Spring Boot Properties”:
https://quarkus.io/guides/spring-boot-properties
RESTful Applications
Eric Deandrea
Both Quarkus and Spring have built-in support for building RESTful applications.
Application development in each technology is similar from a conceptual stand-
point. A developer in each framework constructs classes containing methods
representing RESTful resources or endpoints. These methods additionally declare
specific input and output parameters. Developers place annotations on these
classes and methods describing how to match an incoming HTTP request to a single
method within a single class. Some typical constraints used to match a request
include:
• HTTP method
• For example, GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS.
• URI path
• For example, in the URL https://www.somewhere.com/api/resources/1,
/api/resources/1 is the path.
• Query parameters
• For example, in the URL https://www.somewhere.com/api/resources/
1?param1=value¶m2=value, there are two query parameters, param1
and param2.
• Media types
• Also known as content negotiation, media type headers present in the HTTP
request signify the request body’s format (Content-Type request header)
and what response formats the client can accept (Accept request header and
Content-Type response header).
A RESTful Quarkus application uses JAX-RS (Jakarta RESTful Web Services [3.1],
formerly known as the Java API for RESTful Web Services) for defining endpoints.
This specification was introduced in Java SE 5 and later became an official part of
A Quarkus developer creates resource classes using APIs from the JAX-RS speci-
controller classes, or more
restcontroller classes, which have their own set of standards for rep-
resenting RESTful concepts. Developers familiar with one can quickly become familiar
with the other.
There are nevertheless a few differences when using RESTEasy in Quarkus versus with-
in a Java EE orJakarta EE application:
Underlying Runtime
One fundamental difference between Quarkus and Spring is the choice of the underly-
ing runtime for building RESTful endpoints and its impact on development libraries and
Quarkus JAX-RS applications using the RESTEasy extension use the Eclipse Vert.x reactive
event-loop engine as the default runtime. Quarkus manages a few I/O threads (sometimes
called event-loop threads) to handle incoming HTTP requests. Additionally, Quarkus auto-
matically moves the execution of any JAX-RS resource class methods onto a separate work-
The RESTEasy extension
er thread, enabling a developer to mix and match blocking and reactive programming styles
is also known as RESTEasy
and frameworks within the same resource class. Figure 3.1 shows a high-level overview.
Classic or Classical
RESTEasy.
Quarkus developers can also use the RESTEasy Reactive extension instead of the
RESTEasy extension. This extension is a drop-in replacement for the RESTEasy Classic
extension in most cases, achieving maximum throughput by handling each HTTP re-
quest on the I/O thread rather than moving to a worker thread. This approach is similar
to how Spring WebFlux uses threads. Figure 3.2 shows a high-level overview.
Using the RESTEasy Reactive extension, a developer needs to ensure that resource
class methods do not perform blocking work, just as with Spring WebFlux. A developer
can add the @Blocking annotation to a resource class method to signal that the meth-
od performs blocking work. In that case, Quarkus will execute the method on a separate
worker thread, similar to how the RESTEasy Classic extension works.
Performance using RESTEasy Reactive is far better, even when using the @Blocking
annotation, due to the tight integration between RESTEasy Reactive and Eclipse Vert.x.
Like RESTEasy Classic, developers can mix and match blocking and reactive program-
ming styles within the same resource class. Benchmarks have shown that a RESTEasy
Reactive endpoint using @Blocking still achieves around 50% higher throughput than
the same method using RESTEasy Classic [3.5].
Reactive Libraries
Developers building Spring WebFlux applications are most likely familiar with the Mono
and Flux reactive types provided by Project Reactor [3.6]. SmallRye Mutiny [3.7] is the
reactive library used by Quarkus, providing APIs conceptually similar to the ones found
in Project Reactor. In fact, Mutiny and Project Reactor share a lot of common code.
Mutiny is an intuitive, event-driven, reactive programming library for Java, allowing de-
velopers to express and compose asynchronous actions. Mutiny offers two types: Uni
for asynchronous actions providing either no result or a single value result and Multi to
provide multi-item streams with backpressure [3.10]. SmallRye Mutiny is part of
the SmallRye project [3.8]
Both types are lazy and follow a subscription pattern: Computation starts only when there
and an implementation of
is an actual need for it, known as a subscription. Both Uni and Multi expose event-driven
the Eclipse MicroProfile
APIs, where a developer expresses what to do upon receiving a given event (i.e., success,
Reactive Streams
failure, etc.). Additionally, Multi implements a Reactive Streams [3.11] Publisher and
Operator [3.9].
implements the Reactive Streams backpressure mechanism. Uni does not implement
Publisher, as the Uni subscription is enough to indicate interest in the result it
may provide.
HTTP Method
that indicate the desired action to be performed on a resource. Spring and Quarkus
a given method within a class. Furthermore, the JAX-RS annotations denote only the
HTTP method, whereas the Spring annotations have other metadata associated with
them. Discussion of this other metadata follows in the next section.
Table 3.1 outlines some common Quarkus and Spring HTTP method annotations used
in RESTful applications.
Quarkus Spring
@GET @GetMapping
@POST @PostMapping
@PUT @PutMapping Note: The semantics around
@DELETE @DeleteMapping
which HTTP method to use
in various circumstances is
@PATCH @PatchMapping
outside this book’s scope.
@HEAD @RequestMethod(method = RequestMethod.HEAD)
@OPTIONS @RequestMethod(method = RequestMethod.OPTIONS)
The HEAD and OPTIONS HTTP methods do not have their own Spring annotations.
Spring’s general-purpose @RequestMethod annotation handles these cases.
annotations.
Both Quarkus and Spring [3.16] [3.17] methods have many potential return values that a
developer can specify. Table 3.3 lists some common ones.