Recently in the JVM world you can observe the rise of microframeworks*. As microservices become more and more popular, the number of lightweight libraries is increasing. Thanks to them building REST APIs becomes easier and faster than ever. I want to introduce you to Micronaut, a recently released library that may stir things up in the ecosystem.
What is the Micronaut Framework?
According to the Micronaut’s homepage, it’s a modern, JVM-based, full-stack framework for building modular, easily testable microservice applications. But what does it even mean? A deeper look reveals to us some features that may really appeal.
Because this framework minimizes the use of runtime reflection (and therefore caching its data), the memory consumption has significantly dropped. Also, thanks to this, the throughput should be much improved.
Micronaut ensures blazing fast startup. The AST transformations and annotation processing makes sure that only absolute minimum is done on the start of application. Everything like dependency injection, proxying, aspects is taken care of on compile time. You shouldn’t be surprised when you start your project under 2 seconds.
There are also out-of-the-box features like service discovery, load balancing, Hystrix, dependency injection/IoC, HTTP client and testing helpers. And last but not least, it’s built on top of Netty, so asynchronous programming and Reactive Streams are supported too.
Before we move to the code, I wanted to note that the same team that built the Grails framework is responsible for Micronaut. So I think we’re good to go and there’s nothing to worry about 🙂
Setting up the project
And that’s something unusual. The preferred way of setting up a project is not adding a dependency to your pom/gradle file. Instead, they suggest using SDKMAN! and firing up few commands. Let’s do it:
$ curl -s get.sdkman.io | bash $ source "$HOME/.sdkman/bin/sdkman-init.sh" $ sdk install micronaut
It should work on all the Unix systems. Windows’ users may have to use Cygwin or Posh-GVM.
It feels odd at first, but after generating a project it starts to seem reasonable. Let’s get into interactive mode of Micronaut CLI. Just type “mn” and then “help” into the command line. You should get something similar to the below screenshot:
There are plenty of functions available and I think that they are self-explanatory. If not, you can always use the help command that explains everything really well 🙂 I’m going to generate a default Java project with create-app mn-example
Remember that Micronaut runs smoothly with Java, Groovy and Kotlin.
After a while the project should be ready with a complete configuration. You can run your app right away.
Creating your first service with Micronaut
If you have previous experience with Spring, you’ll feel like home. A basic working controller is contained in the following snippet:
@Controller("/hello") public class HelloController { @Get("/{name}") public String hello(String name) { return "Hello " + name; } }
And the result in the browser:
Reactive programming with Micronaut
Micronaut supports reactive streams out-of-the-box, so there’s not much thinking to be done. Let’s slightly modify the HelloController class:
@Controller("/hello") public class HelloController { @Get("/{name}") public Single<String> hello(String name) { return Single.just("Hello " + name); } @Get("/count") public Publisher<Event<Integer>> count() { return Flowable.just(1, 2, 3, 4, 5) .zipWith(Flowable.interval(500, TimeUnit.MILLISECONDS), (item, interval) -> Event.of(item)).doOnComplete(() -> {}); } }
The first method will return string as soon as its ready, but the second method will send to the client just one integer with 500ms gap between each. The technology that stands behind it is called Server-Sent Events. Shortly, SSE allows client (i.e. web browser) to obtain updates from the server without asking for them.
HTTP Client – not only for testing
Micronaut comes bundled with a full-blown asynchronous HTTP client that’s ready to global use in your projects. You don’t have to limit yourself to tests.
And when it comes to unit testing, it seems really simple:
@TestInstance(Lifecycle.PER_CLASS) class HelloControllerTest { private EmbeddedServer server; private HttpClient client; @BeforeAll public void setupServer() { server = ApplicationContext.run(EmbeddedServer.class); client = server .getApplicationContext() .createBean(HttpClient.class, server.getURL()); } @AfterAll public void stopServer() { if (server != null) { server.stop(); } if (client != null) { client.stop(); } } @Test public void testHello() { HttpRequest<String> request = HttpRequest.GET("/hello/Adrian"); String body = client.toBlocking().retrieve(request); assertEquals("Hello Adrian", body); } }
I think I don’t need to explain anything, it’s pretty clear. Of course we should run it, just to be sure everything works 🙂
Unfortunately I haven’t found a way to effectively test SSEs. I’ll work some more on it, but maybe you have an idea how to do it properly?
Conclusion
Micronaut starts to be seen as something that may mix things up in the Java world. With its speed, low memory foot print, easiness of configuration (or none of it :)) and a nice set of bundled dependencies I perceive it as a growing competitor to Spring Boot. I’m going to keep an eye on this framework and watch its development with great curiosity.
If you liked this post, you can stay in touch with me on Twitter: @a_mrszlk
*If you want to know more about this, read this post on the E4Developer blog
Good one. Looking for way to interact with Kafka streaming and load to HBase…..