In the first tutorial (Quarkus vs Spring Boot - Part 1) we have compared Spring Boot and Quarkus in relation to the core framework capabilities, memory consumption, cloud readiness and ease of development. In the second part of this article series, we will be comparing which are the actual API that you can use to build microservices-like applications using Spring Boot and Quarkus.
The foundations of QuarkusIO
In terms of application development, QuarkusIO aims to ease the application development by including a subset of the core Java Enterprise API which most developers are familiar with and, in addition, brings the innovation of Microprofile API which is an initiative that aims to optimize Enterprise Java for the Microservices architecture.
Here is a bird's-eye-view of QuarkusIO core architecture, although the list of available extensions cannot be exhaustive for the sake of brevity:
One important advantage of adopting Quarkus is the early adoption of Microprofile API, which has quickly become a standard for covering all core aspects needed for Microservices architectures such as:
- The Eclipse MicroProfile Configuration: Provides a unified way to configure your services, injecting the configuration data from a static file or environment variables.
- The Eclipse MicroProfile OpenAPI : Provides a set of Java Interfaces to document your Services in a standard way.
- The Eclipse MicroProfile Health Check: Provides the ability to probe the state of service; for example if it's running or not, if it lacks of disk space or maybe if there is any issue with the database connection.
- The Eclipse MicroProfile Metrics: Provides a standard way for MicroProfile services to export monitoring data to external agents. Metrics also provide a common Java API for exposing their telemetry data.
- The Eclipse MicroProfile Fault Tolerance: Allows you to define a strategy in case of failure of your services, for example configuring timeouts, retry policies, fallback methods and Circuit Breaker processing.
- The Eclipse MicroProfile OpenTracing: Provides a set of instrumentation libraries for tracing components such as JAX-RS and CDI.
- The Eclipse MicroProfile Rest Client which builds upon the JAX-RS API, provides a type-safe, unified approach for invoking RESTful services over HTTP.
On the top of QuarkusIO, you can re-use two core Java Enterprise building blocks such as:
- JAX-RS: provides portable APIs for developing, exposing and accessing Web applications designed and implemented in compliance with principles of REST architectural style.
- CDI: is the Java Enterprise standard for dependency injection (DI) and interception (AOP). Most of the existing CDI code should work just fine, however, it is not yet a full CDI implementation verified by the TCK.
In order to persist data, Quarkus can use the well-known Hibernate ORM and JPA API. Besides it, (not included for brevity in the picture), it is also possible to leverage Hibernate Panache API to simplify and accelerate the development of applications.
Quarkus is not just for HTTP microservices, but also for event-driven architecture. In particular, it simplifies the creation of Reactive application using at its core Vert.x and Netty plus a bunch of reactive frameworks and extensions on top to help developers. Its reactive nature makes it very efficient when dealing with messages (e.g., Apache Kafka or AMQP).
In particular, Quarkus is able to handle both imperative and reactive code at the same level.
For example, you may need to handle a fast non-blocking code that handles almost everything going via the event-loop thread (IO thread). But, at the same time, you might need the traditional (imperative) programming model to create a standard REST application or a client-side application. Therefore, depending on the destination, quarkus can invoke the code managing the request on a worker thread (e.g. JAX-RS) or using an IO Thread to manage a reactive route.
In terms of connectors, Quarkus contains connectors for most common Streaming platforms such as:
- Apache Kafka Connector to send and receive messages to an Apache Kafka cluster
- ActiveMQ connector, using its Advanced Message Queuing Protocol (AMQP)
The foundations of Spring Boot
Spring Boot is an opinionated view of the Spring platform and third-party libraries so you can get started with Spring in a matter of minutes.
Here is a high-level view of the project:
Although Spring Boot greatly simplifies the creation of Spring applications, it is based on the same solid foundations as Spring.
At the core of the Spring framework, there's the Spring IoC container which is responsible to create the objects, wire them together, configure them, and manage their complete life cycle from creation till destruction. The Spring IoC container uses DI to manage the components (called Spring Beans) that make up an application.
The BeanFactory is the actual representation of the Spring IoC container that is responsible for containing and otherwise managing the Spring Beans. The BeanFactory interface is the central IoC container interface in Spring.
The container gets its instructions on what objects to instantiate, configure, and assemble by reading the configuration metadata provided. The configuration metadata can be represented either by XML, Java annotations, or Java code. Spring Boot uses Java annotations and sensible defaults to provide configuration metadata.
In terms of Web application development, Spring Boot can use different embedded Web containers (Jetty, Undertow, Tomcat) and relies on Spring MVC to develop applications using the well-known Model View Controller (MVC) design pattern. Also, there are several template engines which can be used on the top of Spring MVC, the most popular choice being Thymeleaf.
In terms of Microservices development, Spring Boot aims to enable developing production-ready applications in quick time. There isn't an external project like Eclipse Microprofile to coordinate all available frameworks. On the other hand, most of the relevant frameworks are sub-project of the main Spring project or third-party libraries. This way, you have more freedom of choice at the price of a more scattered set of libraries.
Spring Boot Actuator module helps you monitor and manage your Spring Boot application by providing production-ready features like health check-up, auditing, metrics gathering, HTTP tracing etc. All of these features can be accessed over JMX or HTTP endpoints.
Spring REST Docs aims at helping you to produce documentation for your RESTful services that is accurate and readable.
In order to help you developing REST Services, Spring boot has built-in support for web modules to use a @RestController. You can integrate it with HATEOAS to ease the creation of REST Services and, with FeignClient which is an equivalent API of MicroProfile Rest Client.
In order to perform JSON Binding/Processing, Spring Boot uses directly Jackson to allow seamless conversion between JSON data and Java objects and vice-versa.
In terms of configuration, Spring Boot uses its own configuration module to allow you to configure your application configuration using by default a file named application.properties
Then, in order to build a fault-tolerant system, this can be done with the help of Hystrix, latency management, and fault-tolerant system
In terms of Data persistence, Spring uses Spring Data which abstracts from a specific provider (such as Hibernate). This results in a repository abstraction which aims to reduce the effort to implement data access layers for various persistence stores significantly.
Data persistence is related to Transactions, and Spring Boot supports distributed JTA transactions across multiple XA resources by using either an Atomikos or Bitronix embedded transaction manager. JTA transactions are also supported when deploying to a suitable Java EE Application Server such as WildFly.
Finally, in terms of reactive applications, Spring Boot features project Reactor which is a fully non-blocking foundation with back-pressure support included. The Reactive stack includes Spring WebFlux which is a non-blocking web framework built to take advantage of modern processors to handle a massive number of connections.
In this two parts tutorial, we have compared two modern frameworks: Quarkus and Spring Boot.
In the first part, we have stressed the capabilities of Quarkus to create modern Java/native cloud-ready applications with reduced memory footprint. On this side, no doubt Quarkus shows a clear advantage, even if new cloud/native features are being added to Spring Boot which may or may not alter this balance in the future.
In terms of foundations, there's no clear winner from my point of view as both frameworks shine with respect to a specific basis of comparison. In the following table, I'll recap a summary of what we have discussed so far in the hope that it will help you to determine the optimal choice for the next application you will write.
|Basis of comparison||
|Microservices||Embraces the Microprofile API, which is driven by an highly active and responsive community. Based on the enhancements produced in the last two years, I see this more innovative and purely developer-driven.||Provides its own modules to develop modern Microservices architectures with the same goals.|
||At the moment includes basic built-in front-end options (Servlet) and some experimental ones (Qute)||Based on the solid foundation of Spring MVC and includes mature templates (e.g.ThymeLeaf)|
|Maturity||It is a relatively new framework, although derived from production ready Java Enterprise API||Mature, open-source, feature-rich framework with excellent documentation and a huge community|
||Features the most advanced combination of traditional (imperative) programming model and event-based. I see this as a big plus.||Features project Reactor which is a fully non-blocking foundation with back-pressure support included|
|Dependency Injection||Uses CDI. At the moment, only a subset of the CDI features is implemented||Uses its robust Dependency injection Container.|
||Uses frameworks familiars to developers (Hibernate ORM) which can be further be accelerated with Panache. I see more innovation here.||Based on Spring Data abstraction. More maturity here from my point of view.|
|Speed||Best overall application performance.||The abstraction built on the top of Spring makes it generally slower than projects derived from Java Enterprise API.|