Building Serverless Applications with Micronaut
Embracing Scalability and Efficiency
Introduction
Micronaut® is a new framework for microservice development that promises fast startup time, low memory consumption, and compile time dependency injection. It has built-in cloud support that includes, for example, support for multiple discovery services or distributed tracing tools. There is also support for functions that can easily be deployed to AWS Lambda.
In this article, I will focus on creating an application that can be deployed on an AWS Lambda. It is a serverless, event-driven compute service that lets you run code for any type of application or backend service without provisioning or managing servers.
Why Micronaut?
What makes it the next level stuff as a framework for Cloud-Native development? Here are a few reasons:
- Natively Cloud Native
Micronaut’s cloud support is built right in, including support for common discovery services, distributed tracing tools, cloud runtimes, and leading vendors (AWS, Azure, GCP). - Ready for Serverless Development
Micronaut's low overhead compile-time DI and AOP make it perfect for writing functions for serverless environments like AWS Lambda, Azure Functions, etc. - Fast Start Time — Low Memory Consumption
Reflection-based IoC framework loads and caches reflection data for every single field, method, and constructor in your code. Whereas with Micronaut, your application startup time and memory consumption are not bound to the size of your codebase. Micronaut is built around GraalVM. Micronaut features a dependency injection and aspect-oriented programming runtime that uses no reflection. This makes it easier for Micronaut applications to run on GraalVM.
Micronaut apps start in a tenth of a millisecond with GraalVM! - Built with Non-Blocking HTTP Server on Netty
With a smooth learning curve, Micronaut’s HTTP server makes it as easy as possible to expose APIs that can be consumed by HTTP clients. - Refreshable feature
@Refreshable
is another interesting scope offered by Micronaut. You can refresh the state of a bean by calling the HTTP endpoint/refresh
or by publishingRefreshEvent
to the application context.
Setting Up Your Environment
Before we begin, make sure you have the following installed:
- JDK 8 or later
- Micronaut CLI
- AWS CLI
- An AWS account
Creating a Micronaut Project
First, let’s create a new Micronaut project using the CLI.
$ mn create-function-app my-serverless-app - features aws-lambda
This command will generate a new Micronaut project with the AWS Lambda feature. Navigate to the newly created my-serverless-app
directory:
$ cd my-serverless-app
Implementing the Lambda Function
@FunctionBean("micronaut-function")
public class MicronautFunction implements Function<String, String> {
@Override
public String apply(String request) {
return new StringBuilder(request).reverse().toString();
}
}
The implemented functions get a String as input and simply return the reversed String as an output.
Steps to deploy using Lamda
Create a Lambda Function. As a runtime, select Java 11 (Correto).
Create an executable jar including all dependencies and upload your code:
$ ./mvnw package
To deploy the function to AWS Lambda, there is a deployment script (lambda-deploy.sh
). This script builds the project and creates a new S3 bucket. Using the AWS CLI, it uploads the artifacts to the S3 bucket and creates a Server Application Model — sam template. Using this template, the script creates an AWS CloudFormation stack that deploys the functions to AWS Lambda.
We will use the AWS Console to test out Lambdas as this is the easiest way to view the startup/execution time. Using a simple test event, we can easily trigger our Lambda functions.
The function worked, and we received the reversed String. Another way we could test our lamdas would be to use the AWS CLI, in this case, you won’t get the execution time as easily.
$ aws lambda invoke --function-name FUNCTION_ARN --payload "\"Hello World!\"" --log-type Tail response.txt
After we are finished with our testing, we can get rid of the functions by simply using the cleanup.sh
script, it deletes the created bucket and also the CloudFormation stack.
Conclusion
In this blog post, we have demonstrated how to develop a serverless application using Micronaut and AWS Lambda. By leveraging these technologies, we can create scalable, cost-efficient applications with reduced operational complexity. we’ve explored the process of developing a serverless application by harnessing the power of Micronaut and AWS Lambda. These technologies, when used in tandem, offer a dynamic solution for building applications that are not only scalable but also highly cost-effective, all while minimizing the operational overhead typically associated with managing traditional server setups.