Creating your very first microservice with Micronaut and Kotlin

Jaime Dantas
Apr 7 · 7 min read
Image by Author

You’re probably asking yourself, what a heck is Micronaut? Why not Spring Boot? If so, this is the post for you. You’re not alone! This is because these questions are often asked by many Spring programmers when first introduced to Micronaut.

With that in mind, I wrote this post to address some of the most common questions that may arise with the use of new frameworks like Micronaut. In this post, I’ll explain the major benefits and drawbacks of Micronaut when compared with Spring Boot, and I also walk you through your very first Kotlin microservice with the Micronaut Framework.

Micronaut vs Spring

It is no wonder that Spring Boot is one of the best frameworks for web development on top of the JVM. It is also well-known that Spring Boot loads its beans during startup time, which is perhaps one of the biggest disadvantages it has against frameworks like Micronaut.

Micronaut is a pretty recent full-stack framework with support to Java, Kotlin and Groovy. Without question, fast startup is the best advantage of Micronaut when compared with Spring. This is because Micronaut compiles and packages all its beans during building time, not startup time like Spring. As a result, it not only improves the application startup time, but also uses less memory during runtime.

Why is this important, you may wonder? Well, the answer to this question is crystal clear: serverless computing. In a scenario where web applications are run on serverless services and containers, this comes handy and it becomes a necessity nowadays.

However, Micronaut comes with a few downsides with it. Like every new tech released on the market nowadays, documentation and resource availability is fundamental for understanding and implementing it. Since Micronaout has just a couple of years of existence, this problem can bring some challenges for the initial stage of adoption. In addition, not all features we have on Spring Boot are available on Micronaut yet. To address this issue, Micronaut’s team is working around the clock to release updates so it can have all functionalities we are used to working with.

Micronaut with Kotlin

Enough said, show me the code!

Like its older brother Spring, Micronaut has its own startup project as well.

However, you can use the already built microservice we describe here on the GitHub repository below.

For this quick example, we’ll try to apply the Domain Driven Design as much as possible. Let’s create our packages as follows:

root
└──configuration
└──controller
└──model
└──service
└──validators

Our API will return a message whenever we call its endpoint. The first classes we’ll create are our models. For that, we want a simple model to be returned by our API and another one for the input.

Our Resource model will contain only one field which is our input, whereas the HelloWorld model is our returned message. Moving on, we need to get some parameters from our configuration fileapplication.yml. We want to get the following parameters:

microservice:
processing-time: 100
threads: 2
return-message: Hello World!

To do so, let’s create a class under the configuration package named PropertiesConfiguration. If you’re familiarized with Spring, this process is identical in both frameworks, except that you need to initialize the variables on Micronaut.

Now that we got this out of the way, we need to create our controller. Once again, here we have the same structure seen in Spring. Note that the @Autowired notation we use with Spring is replaced by @Inject on Micronaut. Apart from that, everything is about the same.

Note that we inject the class LoadSimulator. This will be our service, and it will be implemented further on. Now it’s time to create our validator. Of course! We’ll have validations on top of our business logic.

There are several ways to perform validations of business logic, but one I really appreciate and am in favour of is fluent validation. This approach is used to create rules and validations on top of business logic. In this example, we’ll use the Java Fluent Validation created by Marcos Vallim to implement our validations.

The way we perform our validations here is by writing rules for a specific model we pass to the validator. Each and every rule has its own purpose, and it can be viewed in three distinct steps: must be, when is, then results in. We also have inline validations and different control levels in case you want to play with it.

We’ll check if the resource ID the client sends us is in the UUID format, e. g. “8e4b8eb4–2b4c-426f-8878–671fa0f9d87e”. If it not in this format, we’ll return a message saying this resource ID is invalid. Note that we can have rules for each field within a specific class.

Now the RestController we created makes more sense, right? Let’s see what our controller does. It has a GET endpoint by which the client sends a resource ID and fetches a HelloWorld model. The first step is to validate the input by calling our ResourceValidator. By calling the method validationResult.isValid(), we can see whether our input is valid or not. Finally, we encapsulate the result of the Fluent Validation into our response when it is not valid. By doing this, we get a nice message whenever we input the wrong data into our API. The example below is for the input “invalidId”. Note how nice the response looks like. The HTTP Status code for this case is sent as BAD REQUEST.

[
{
"message": "The Resource Id is not valid",
"field": "id",
"attemptedValue": "invalidId"
}
]

Back to our service LoadSimulator, we will create a service that simulates some work with multithreading. We will use Kotlin Coroutines to launch some async routines based on some parameters present on our application.yml. Each routine will perform some math calculations and put itself into hibernation mode for 50 ms before joining its main thread.

Although it may scare you at the first glance, it is not complex to understand. This service is useful for adjusting the approximate response time we want our API to have at the same time we make sure we’re performing some multithreading computation during this period. You need to define the number of threads and the processing time in the application.ymlfile.

I bet by now you were wondering where is our unit tests. Creating good unit tests is of utmost importance for any software system. Our case is no exception. Even though this quick example has almost no business logic attached to it, we need to create our unit tests. Let’s first create our ResorceValidation test.

We need to annotate our test with @MicronautTest to use the Micronaut Test Framework. You can use other ones like JUnit or combine them on your test. To keep things short, I showed here only one unit test, but there are many more implemented. Next, let’s see how we implement a unit test for our controller. Here, we’ll create two tests: one for testing a bad input and one for testing the successful return of a custom message.

Note that we’re loading into our test our application.yml file. This is because we want to change the property return-message. We use the RxHttpClient from Micronaut to call our controller.

Finally, we need a test for our LoadSimulator service. We need to test if our service is indeed taking the approximate time it should take for processing a given call. For that, we will need to set the number of threads to 1 and test for 1 second.

Note this service is heavily influenced by the number of cores you have on your CPU, so don’t take the property processing-time as the response time of our API.

Swagger UI

In order to test our API, we’ll use the Swagger interface with our API. If you are not aware of this framework, it is used for documenting your service and running an HTTP client where you can play around with your service by sending a bunch of request to it. You may refer to its documentation to know more about it.

To view the Swagger interface, run our API service:

$ java -jar load-simulator-0.1.jar

Then, go to the following URL on your browser:

http://localhost:8080/swagger/views/swagger-ui/

You should see this web interface.

Swagger Interface

Here, you can try sending an HTTP request to your API and analyze the response.

That’s it, folks! I hope you have learned a bit more about Micronaut with this post. Don’t forget that you can get the complete code on the GitHub repo for this project.

About Me

I’m an M.A.Sc. student at York University, and a Software Engineer by heart. During the past decade, I’ve been working in several industries in areas such as software development, cloud computing and systems engineering. Currently, I’m developing research on cloud computing and distributes systems.

You can check my work on my website if you want to.

Thanks for reading it!

References

Micronaut Framework — https://micronaut.io/

Reverse Engineering

Ideas, concepts, tutorials, and tips about the computer…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store