Quarkus 1
Quarkus 1
05 Foreword
06 Acknowledgments
08 Chapter 1–Introducing Quarkus
Brief History of Java
Introduction of Spring
Emergence of Microservices
Spring Boot
Challenges of Microservices
Challenge #1: Composition of Distributed Applications
Challenge #2: Infrastructure and Operations
Quarkus: The Solution to Today’s Challenges
Container First
Built on Standards
Developer Productivity and Joy
Unifying Reactive and Imperative
Summary
19 Chapter 2–Getting Started with Quarkus
Prerequisites
IDEs
Extensions
Spring API Extensions
Creating a New Project
Generating a Project
Project Structure
Controlling Dependency Versions
Quarkus Dev Mode and Live Coding
Dev UI
Dependency Injection
Scopes
Example
Lifecycle Callbacks
Native Image
Resident Set Size
Testing
Continuous Testing
Unit Testing
Native Image Testing
Summary
45 Chapter 3–RESTful Applications
Underlying Runtime
Reactive Libraries
HTTP Method
Routing HTTP Requests
Building RESTful Endpoints
RESTful Endpoint Class Structure
RESTful Endpoint Examples
Exception Handling
Testing RESTful Endpoints
RESTful Endpoint Test Class Structure
RESTful Endpoint Test Examples
Testing Exception Handling
Server-Sent Event Endpoints
Testing Server-Sent Event Endpoints
OpenAPI Documentation
Summary
71 Chapter 4–Persistence
Evolution of the Java Persistence API
JPA Abstractions
Spring Data JPA
Quarkus Hibernate with Panache
JPA in Action
JPA Testing
Reactive Data Access
Spring Data R2DBC
Quarkus Hibernate Reactive with Panache
Reactive Data Access in Action
Reactive Data Access Testing
Summary
Environment Variables
Monitoring
Metrics
Distributed Tracing and Logs
Summary
147 Appendix
149 About the Authors
The year is 2021, and for the 21st year in a row, the Java ecosystem
once more is confronted with the “Java is Dead” meme. This time,
industry observers state that the Java ecosystem will not pivot to
efficient runtimes and frameworks for microservices deployed on
resource-constrained containers. Naturally, the Java community has
ignored the meme and responded with a wave of new runtimes and
frameworks.
One of the firm leaders in this new wave of “runtime plus framework”
stacks is Quarkus. Quarkus combines standardized enterprise Java
APIs (from Java Enterprise Edition, Jakarta Enterprise Edition, and
MicroProfile) to build your services and then run as a tightly packed,
precompiled, and resource-efficient native image (via GraalVM). An
example of this is Eclipse Adoptium (previously AdoptOpenJDK).
We moved our API to use Quarkus, and it’s been brilliant both in
developer productivity and performance, serving up to 300 million
requests in the past two years from a single small instance.
Given the title of the book, and especially if you’re a Spring develop-
er, I suspect you might be thinking “marketing hype” right about now,
right? For me, the paradigm that Quarkus brings is a major one for
Java. This is one of these moments in your career when you should
take stock and explore a new technology in-depth! This book makes
it easy to do that, providing like-for-like examples of your favorite
Spring development patterns mapped to their Quarkus equivalents
(don’t panic, there are many similarities) and giving you an in-depth
understanding of the fundamentals at play under the hood.
Eric Deandrea
I’ve spent most of my software development and architecture career building Java ap-
plications and application frameworks. Over the last ten years, I have focused on building
opinionated frameworks based on Spring and architecting DevOps solutions. My experi-
ence with Spring led my employer, Red Hat, to approach me about writing this book.
There are many similarities and differences between Quarkus and Spring. When getting
started with Quarkus, I found many Quarkus books, guides, and tutorials, but not many
explicitly tailored to developers familiar with Spring concepts, constructs, and con-
ventions. I was excited to use my Spring experience to help showcase and explain the
anything more than a blog post or short article before. I didn’t even know how to get
started. Luckily, I work with many talented people who were there to help along the
way. Each and every one of the following people played a key role. This book would not
have been possible without the contributions of each person.
First, thank you, Syed M. Shaaf, for getting me involved in this project and helping me
get started. You helped me get organized and develop a table of contents. The initial
table of contents was aggressive and needed to be scaled back, but it helped drive the
overall topics and structure that we wanted to cover in this book. A big thank you is also
needed for helping with decisions around publisher selection.
Thank you, Daniel Oh, for your initial reviews of the chapters I authored. You were
always there to help me with ideas in the writing and the examples, as well as for your
help testing all the examples. A huge thank you for authoring Chapter 5: Event-Driven
Services. The book would not have been a success without your time and contributions.
Thank you, Charles Moulliard, for your countless hours of time and effort reviewing
chapters for technical accuracy and suggesting improvements. Thank you as well for
organizing reviews of all the example projects. A huge thank you for authoring Chapter
6: Building Applications for the Cloud. I don’t know what I would have done without your
involvement and dedication to this project, especially since all of your contributions fall
outside your daily responsibilities. Your time and effort are very much appreciated!
Thank you, Georgios Andrianakis, for your help reviewing the examples used in the
chapters and pushing raised GitHub issues and pull requests through the process.
Thank you as well for being a sounding board for ideas and questions. I really appreciate
you dealing with my constant nagging, even when it was late at night for you.
Thank you, Aurea Munoz and Gytis Trikleris, for your help reviewing and improving the
quality of the examples used in the chapters. A fresh set of eyes is always a good thing.
Your contributions made the examples clear and easy to follow.
improving Chapter 4. I am extremely grateful that you were willing and able to step up
and help with something that was outside your normal activities.
Thank you, Martijn Verburg, for graciously agreeing to write the foreword for the book.
Having someone of your stature within the community embracing Quarkus says a lot
about where Quarkus stands today.
Thank you to the Red Hat Developer team for all of your help and support, from
managing the process so smoothly, and thank you, Andy Oram, for the hours of editing
and help to organize the content into its current form. The book would not have been a
success without both of you.
Finally, thank you to my wife, Rachel, my daughter, Emily, and my son, Ethan, for supporting
me throughout this process. You might not understand what I wrote, but you were always
there to listen to me talk about it. You were excited when I was excited, which helped drive
Daniel Oh
5 and review the other chapters. This opportunity enabled me to take many technical
deep-dives into the Spring and Quarkus frameworks. I would also like to thank my lov-
ing and patient wife and kids for their continued support, patience, and encouragement
throughout the writing of this book.
Charles Moulliard
At the beginning of this book’s adventure, Eric Deandrea and Syed Shaaf contacted me
to review the book content and examples. Ultimately they convinced me to write the
cloud material in Chapter 6. This has been a fantastic experience. I would like to thank
them for giving me this opportunity, as speaking about the cloud is not the easiest task,
nor is writing a chapter of a book as a non-native English speaker.
Thank you to the Snowdrop team and my associates, who took the time to play with
the different examples and made proposals to improve the code and wording. Special
thanks to Aurea Munoz Hernandez and Georgios Andrianakis for their support and
encouragement.
blocking problem discovered when a change was made by Kubernetes to move the API
of the Ingress resource.
Thank you, Dimitri and Bruno, for giving me as a manager the time needed to be part of
this project and to accept some delays when my weekly reports were not ready on time.
Introducing Quarkus
Eric Deandrea
As interest grows in microservices and containers, Java developers have been struggling
to make applications smaller and faster to meet today’s requirements. In the modern
This chapter will introduce Quarkus and highlight the key drivers behind its creation.
Because many Java developers already know Spring and see Quarkus as an alternative,
we’ll showcase fundamental differences between Quarkus and Spring while also high-
lighting similarities. These differences make Quarkus an ideal runtime for Java applica-
Note: We use the general
tions that target modern platforms and architectures, such as microservices architec-
term “Spring” to cover Spring
tures, event-driven architectures, serverless, functions-as-a-service, edge computing,
Framework and any other
and IoT. The remaining chapters will help developers familiar with Spring Framework learn
modules within the Spring
how to do familiar things with Quarkus while highlighting key fundamental differences.
ecosystem, including Spring
Boot. Source code for all
Brief History of Java examples used throughout
In today’s world, application architects and developers have many technology choices this book is located at https://
to solve a business or technical problem. Java remains one of the most widely used github.com/quarkus-for-
programming languages to build applications today. Within Java, there are many tools spring-developers/examples.
and frameworks to help developers build applications.
Java was created when the cloud, containers, and container orchestration systems such as
Kubernetes [1.1] did not exist. The historical Java stack consisted of applications deployed
into Java application servers. In that architecture, each application server hosted multiple
applications and provided additional services, such as transaction management, caching,
connection pooling, and more. These application servers focused on providing the Java
deemed “heavyweight.” These application servers took minutes to start up and consumed
large amounts of memory, while their response times were measured in seconds.
Some time later, other application servers supporting a smaller subset of the J2EE
projects and web containers, catered to web applications not requiring the full J2EE
-
The past 15-20 years have seen many optimizations to the Java application stack and the
Java Virtual Machine (JVM) to support running large heaps and highly dynamic frame-
works that make decisions at runtime, particularly at application startup.
Introduction of Spring
Spring was introduced to the open source community in 2003. At that time, the J2EE
-
opers needed a faster release cadence for features. Spring brought in another popular
trend where developers could build the same enterprise applications using a light-
er-weight stack based on “plain old Java objects” (POJOs) while still complimenting
stack made Spring Framework an ideal choice for building “lighter” applications. These
applications did not require the same amount of memory and CPU resources needed
by a Java application server because they could be deployed into any runtime support-
For many years after, Spring continued to evolve and grow, providing new features that
-
saging, authentication and authorization of users, and web services. Many architects
and developers have promoted Spring as arguably one of the most popular frameworks
to build applications.
Emergence of Microservices
Over time, large, monolithic applications became harder to scale. Many teams needed
to work in parallel on the same project in the same source code repository. Any change
to one part of an application affected other developers working on other parts of the
application, while also forcing testing and redeployment of the entire application. A sin-
gle application deployment may have consisted of tens of servers and required hours
handle increased loads that might affect only a subset of its capabilities.
-
bilities faster. Gone were the days of waterfall design, where an entire system needed
to be designed before a line of code was written. Agile development helps enable
teams to deliver smaller subsets of business capabilities faster. It also allows for smaller
development teams, where each team can focus on a small subset of the capabilities an
overall system provides.
architectures.
and memory, which is not always possible in a monolithic application. A single business
capability can scale independently of other capabilities.
Spring Boot
The shift towards microservices also led to the introduction of Spring Boot in 2014.
One of the most powerful features of Spring Boot was its ability to package all the
application without deploying it into a separate Servlet container. Instead, Spring Boot
embeds a web container (i.e., Apache Tomcat, Eclipse Jetty, or Undertow) inside the
application’s JAR. All that was required was a JVM. This packaging mechanism helped
across all of the underlying Spring modules. Additionally, Spring Boot gave developers
when moving from one environment to another, such as from integration testing (IT)
to quality assurance (QA) to production.
Challenges of Microservices
A microservices architecture, while solving some challenges, introduces others. Micro-
services create complexity for developers and operations teams alike. The distributed
architecture gives rise to challenges that need to be addressed. Microservices are also
Reactive systems
them more maintainable and extensible. Reactive Systems are also resilient when faced
with failure. The Reactive Manifesto [1.2] was introduced in 2014 as a set of guidelines