Enterprise Java

Microservices: Quarkus vs Spring Boot

1. Introduction

In this article, we will explain two important Microservices. Let’s make a comparison between Microservices: Quarkus vs Spring Boot.

Nowadays, when engineers have started to grow to vary in deploying their applications into the cloud ecosystem, they prefer not having to take care of infrastructure needs at all. This means that technologies like AWS Lambda keep on rising due to the advantages they provide related to deployment cycles and automatic spin-up of scalable solutions, they also have a pickle of disadvantage with them with a concept called cold start. For example, when it comes to cold start issues with AWS Lambda, it is very common for people saying such problems (and I quote):

Before my cold start time would be like 10 seconds and every subsequent call would complete in like 80 ms.

Stackoverflow

Problems like the above make the time to boot and time to first request an extremely important factor to take into account about what technology we used to develop and deploy our serverless functions because that can drive success or failure in our application. That is where Quarkus comes in. In this lesson, we will try to take a look at what problems each of these frameworks solves for us (and what problems they do create). With the information in hand, we hope you will be able to make a decision for your next world-changing idea.

2. What is Quarkus?

QuarkusIO, the Supersonic Subatomic Java, promises to deliver small artifacts, extremely fast boot time, and lower time-to-first-request. When combined with GraalVM, Quarkus will compile ahead-of-time (AOT).

Let’s try to elaborate on some terms before we can get into the details:

  1. JIT Compiler: When we write a Java program and compiles it (say, using the javac compiler), the compiler converts the source code to bytecode. This bytecode cannot be read by a processor so, at the next level, an interpreter interprets the bytecode and makes the processor capable of understanding this code. Now we all know, interpreters are slow! To avoid this, JVM runs another compiler that compiles this bytecode into machine code which can be read and executed by any processor. This is called Just in time compilation, as the code is converted into machine code only when it is being executed. The advantage with JIT compilation is that only hot methods (methods which will be executed) are compiled and hence, machine code is much more optimized. But it also means that the compilation process takes longer.
  2. AOT Compiler: Some compilers (like Graal) can be used to perform a total compilation of code before that code is executed (opposed to JIT compilation). This means that all methods (not only hot methods) are compiled into the machine code. The advantage with Ahead of Time compilation is that it is a lot faster, as the step of finding hot methods is not part of the compilation process.

I would like to re-visit what I mentioned for Quarks. To simply put, it is a framework that helps you to bootstrap applications and promises to deliver smaller artifacts. But, smaller to what? Now that will be a good time to introduce the next candidate, Spring Boot.

3. Spring Boot

Spring Boot is not a new name but something which has already established a very strong foot in the web community to develop production-ready applications whose TTM (time to market) is very low. It is really surprising how you can create a fully-fledged Spring application which just one Java class inside it. Possibly, that is why it is one of the best candidates to create microservices.

You can also check our article on What is Spring Boot.

4. Making First application

In this section, we will take a look at what we need to do to make the first hello world application with our two contenders which will be the best way to go toe-to-toe with each other. We will start with Spring Boot framework and then look at Quarkus how it accomplishes the same task and how it compares to the Spring Boot framework. Let’s get started.

4.1. Spring Boot

Whenever I am making a new application with Spring Boot, Spring Initializr tool is my go-to webpage. When I created a new application and added a new API endpoint in the only Java class my project will have, there were only two files that mattered. First one being pom.xml which looks like:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.3.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.javacodegeeks</groupId>
	<artifactId>hello-spring-boot</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>hello-spring-boot</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>RELEASE</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

The next part is the only Java class we have in our application:

HelloSpringBootApplication.java

package com.javacodegeeks.hellospringboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class HelloSpringBootApplication {

	public static void main(String[] args) {
		SpringApplication.run(HelloSpringBootApplication.class, args);
	}

	@RequestMapping("/")
	public String index() {
		return "Greetings from Spring Boot!";
	}

}

And that’s it. Can you believe it? The above two classes made a production-ready microservice ready to be deployed as an executable JAR file. The @RestController the annotation above informs the Spring Container that if there are any exceptions that are raised in this class are fine to be passed on to the client itself.

You can try executing/running above application with the following command:

Command to run Spring Boot application

./mvnw spring-boot:run

If you must know, here is the project structure we used in IntelliJ IDE (irrespective of IDE):

Quarkus vs Spring Boot - Spring Boot Hello World
Spring Boot Hello World project structure

The above project looks very simple (which it is) and that is what is the core idea behind Spring Boot being built on top of Spring MVC. Sometimes, there are moments of a surprise what better way of using Singleton (not strictly) and Template pattern within a framework than to reduce all that boilerplate code all of us have to include just to get an application do minimal task.

4.2. Quarkus

Now that we have come this far by laying out how you can get started with a Spring Boot application, it is time to move on to accomplish the same task using Quarkus. We will start by creating a new project with a command line using a simple command which makes use of one of the Quarkus maven plugin. Use the following command to create a similar project which we created for Spring Boot:

Command to create new Quarkus project

mvn io.quarkus:quarkus-maven-plugin:0.13.1:create \
    -DprojectGroupId=com.javacodegeeks.quarkus \
    -DprojectArtifactId=hello-quarkus \
    -DclassName="com.javacodegeeks.quarkus.HelloResource" \
    -Dpath="/hello"

This will start to download the many dependencies which are needed to build a new Quarkus project.

Creating a new Quarkus Project

This will generate a new project a HelloResource with a /hello endpoint already created as part of the setup, configuration, Maven project, and Dockerfiles. Once you start to go through the project created, you will find many key differences, the REST endpoint class is much simpler:

HelloResource.java

package com.javacodegeeks.quarkus;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class HelloResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

The above code is a very simple snippet of how JAX-RS endpoints work and the maven plugin set that up for us in no time. There is no point in posting the exact maven file except mentioning the fact that it is quite cumbersome to go through with it. At this point, we should be able to run our project using another very simple command:

Command to run Quarkus application

./mvnw compile quarkus:dev

5. Quarkus: Pros and Cons

Usually, people try to compare two frameworks and try to identify who is the winner too soon. The issue is, it all depends on the use-case of the problem you are trying to solve. Let’s look at some of the pros and cons we noticed for Quarkus:

  1. The documentation offered by Quarkus is great and highly competitive when you try to check differences with Spring Boot. Although the community support for Spring Boot is unbeatable (today) but the documentation for Quarkus is quite simple and long.
  2. Graal VM installation is not something everyone will be able to accomplish easily. We need to check OS-specific binaries and packages and that is not an easy task, or at least not straightforward.
  3. It does deliver on one thing it markets too much – the app booting time (an important ground for improvement in Java-based applications) by using the build-time meta-data processing logic and more importantly building standalone native images using Graal/Substrate VM.
  4. Worth mentioning again, community forums like SO are not filled with solutions to some weird problems you can get in with Quarkus
  5. It is good for serverless deployment use cases like AWS Lambda as we already mentioned, boot time can seriously help you to reduce the overall cost you pay for the execution
  6. We can never forget the fact that it’s built on top of known Enterprise standards like JAX-RS etc. and we run our applications in an optimized runtime, either via a native executable or using a Java runtime.
  7. The hot reloads with Quarkus are even faster than Spring Boot.
  8. The roadmap for Quarkus looks quite interesting and is quite up to date and is maintained. I really wish something like this was managed for Spring Boot as well.

With these points in mind, I am still inclined to give Quarkus a try for my next production microservice and one of the data pipelines whose task will be to batch process some data, perform an ETL operation and get it over with.

6. Spring Boot: Pros and Cons

Most people will think why is there even a need to include this section but it is important to highlight some of the issues which lie inside Spring Boot skeleton as well:

  1. We all know Spring Boot applications can take ages to start. Due to the fact that the dependency management in Spring Boot is largely dependent on starter modules that are provided with the framework, the modules bring over a ton of dependencies with it which in turn affects the boot time and application overall performance.
  2. The memory footprint of a Spring Boot application is quite large. This again comes from the fact that how many dependencies a Spring Boot application has to load and keep in memory when it starts and runs inside a container. This means that it might not be possible to run a little heavy AWS Lambda functions due to the memory constraints it presents (at least not without investing heavy time in it).
  3. As already mentioned, the community support for Spring Boot is outstanding and so does its documentation.
  4. The speed at which you can include new libraries and still get up and running with Spring Boot is marvelous. The use of the Template design pattern means you can just include a dependency within the pom.xml file and that’s all you have to do to get to start that dependency even if it is as complex as communicating with an in-memory MongoDB database instance.

I am sure the last point is something due to which we mainly use Spring Boot. Because it makes our life simpler and more do we need!

7. Conclusion

Although this article might not have provided you with a clear and indicative answer as to which framework should be your next choice when you think about deploying your next microservice, this should definitely help you to get started and see for yourself what you are getting into when you start to work with applications with both of these frameworks.

As Quarkus is gaining a lot of traction lately, there are several quickstart projects for us to try Quarkus at Quarkus GitHub repository which I very strongly recommend doing as how it feels like, this project will go a very long way. Having said that, we already know the power of Spring Boot and what it brings to the table. It has also come a long way when we started to develop Spring applications using Spring MVC and having to do those many configurations which were cumbersome and difficult to handle but those days are now over with Boot coming in.

We will be very interested in checking up what was the use-case due to which you chose one another so please share it in the comments below.

8. Download the Source Code

All the source code of this lesson can be found here for download.

Download
You can download the full source code of the examples here: Microservices: Quarkus vs Spring Boot

Shubham Aggarwal

Shubham is a Java Backend and Data Analytics Engineer with more than 3 years of experience in building quality products with Spring Boot, MongoDB, Elasticsearch, MySQL, Docker, AWS, Git, PrestoDB tools and I have a deep knowledge and passion towards analytics, Micro-service based architecture, design patterns, antipatterns and software design thinking.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button