How to build a microservice with AWS Lambda in Groovy

(in less than 5 minutes)


At AgoraPulse, we love to focus on building our applications and pushing new features instead of managing/scaling infrastructure. That’s why our tech stack relies heavily on:

  • AWS managed services (Elastic Beanstalk, S3, SQS, DynamoDB, Kinesis, etc),
  • Groovy ecosystem (Grails, Gradle, Spock, GPars, etc).

When AWS announced Lambda in November 2014, I got pretty excited but only nodejs/javascript runtime was supported at that time.

AWS Lambda is a compute service that runs your code in response to events and automatically manages the compute resources for you, making it easy to build applications that respond quickly to new information.
Source: Why AWS Lambda is a Masterstroke from Amazon

In June, AWS finally expanded Lambda programming model to support Java 8 runtime and therefore various JVM languages such as Groovy. Shortly after that, in July, they introduced API Gateway which tightly integrates with AWS Lambda to allow you to create completely server-less APIs.

Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale.

Yesterday, I finally took the time to experiment with all of this by building an HelloWorld microservice (nanoservice?) example in Groovy.

Do you remember my post on The evolution of software architecture (italian food perspective)?

In this article, we are going in 100% ravioli mode.
Bon appétit !


On the Groovy side

First step: we need a deployment package. Let’s convert the Getting started in Java example to Groovy with a Gradle build:

  • create a root directory hello-world for your project,
  • configure the project as a Groovy project by adding the following build.gradle,
apply plugin: 'groovy' // Groovy plugin 
apply plugin: 'java'

group 'example'
version '1.0-SNAPSHOT'

repositories {
mavenCentral()
}

dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.4'
compile 'com.amazonaws:aws-lambda-java-core:1.0.0'
}

task buildZip(type: Zip) {
from compileGroovy
from processResources
into('lib') {
from configurations.runtime
}
}

build.dependsOn buildZip
  • add the following Groovy class in hello-world/src/main/groovy/example/Hello.groovy,
package example

import com.amazonaws.services.lambda.runtime.Context

class Hello {

// Our lambda function handler
String myHandler(data, Context context) {
context.logger.log "received in groovy: $data"
"Hello ${data}"
}

}

Note: AWS Lambda supports input/output of primitive Java types, POJO types, and Stream types.

  • run gradle build to generate the .zip deployment package (by default hello-world/build/distributions/HelloWorld-1.0-SNAPSHOT.zip).

On the AWS Lambda side

Next step: let’s create our Lambda function.

  • signup/signin to https://console.aws.amazon.com,
  • go to Lambda and create a lambda function called HelloWorld (you can skip the step 1 with nodejs blueprints),
  • select your .zip deployment package (hello-world/build/distributions/HelloWorld-1.0-SNAPSHOT.zip) and enter your handle name example.Hello::myHandler,
  • create a role by choosing the Basic execution role from the list (if this is your first time, AWS Management Console will create an IAM role called basic_execution_role in your account with an access policy that allows only permission to write logs to CloudWatch Logs),
  • review your settings and create the function.

Once your function has been created, you can test it with some sample input, in our case the following JSON string:

{
"firstName": "Benoit",
"lastName": "Hediard"
}

When testing the function, you should get the following output:

"Hello [firstName: Benoit, lastName: Hediard]"

You can see that AWS Lambda automatically serializes and deserializes the input and output to match your function input/output data type : the JSON String input has been automatically converted to a Groovy Map.

Your Groovy code is now running in AWS Lambda!

On the AWS API Gateway side

AWS Lambda are often used to react to various AWS event sources (S3, DynamoDB, Kinesis, SNS, etc) but you can also invoke them over HTTPS by defining a custom REST API and endpoint using Amazon API Gateway:

  • in your Lambda function settings, add an API endpoint named LambdaMicroservice with the resource name HelloWorld,
  • select POST method and Open with access key security,
  • go to API Gateway and test your API by entering some JSON string in the POST request body, you should get your lambda function result as a response.

But our HelloWorld lambda function currently returns a String, so let’s return a Map to generate a valid JSON response.

  • edit your Hello groovy class
package example

import com.amazonaws.services.lambda.runtime.Context

class Hello {

Map myHandler(data, Context context) {
context.logger.log "received in groovy: $data"
[greeting: "Hello ${data?.firstName} ${data?.lastName}".toString()]
}

}
  • run gradle build and upload the generated .zip to your HelloWorld Lambda function,

Note: you can also use AWS Gradle plugin (https://github.com/classmethod-aws/gradle-aws-plugin) to update and invoke/test your Lambda function directly from Gradle.

  • re-test your API, et voila !!!

How will it scale?

There are no fundamental limits to scaling a function. AWS Lambda will dynamically allocate capacity to match the rate of incoming events.

That great, but how much will it cost?

With AWS Lambda, you pay only for what you use. You are charged based on the number of requests for your functions and the time your code executes. The Lambda free tier includes 1M free requests per month and 400,000 GB-seconds of compute time per month.

I’m always amazed by the pace of innovation at AWS. That’s another managed services added to the AWS toolbox and this one just blows my mind. It might profoundly change the way we architecture, develop and deploy software.

A microservice built and deployed in less than 5 minutes.
No server, no instance, no container, no app server.
Just runnable code in the cloud!

Note: we’re hiring! Are you kick-ass fullstack or front-end dev that want to work on AWS, Angular 2, Java or Groovy? You must contact me to join our dream team in Paris!

If you liked this article, please hit the ❤ button to recommend it. This will make it easier for other Medium users to discover this.