Serverless application with AWS Lambda and Kotlin. Part 2
Part 2 — First blood: Java + Kotlin + AWS Lambda
This series of articles consists of 4 parts:
- Intro to Serverless applications and Functions-as-a-Service
- First blood: Writing functions in Kotlin for Java platform on AWS Lambda (you are here)
- Warmup optimization: Writing functions in Kotlin for Node.js platform on AWS Lambda
- Using familiar tools: Writing functions in Kotlin for for Java platform using Spring Cloud Functions on AWS Lambda
Purpose of this part of series is to show how to create a lambda function on AWS Lambda based on Java platform with Kotlin programming language.
All source code can be downloaded from Github
Creation and testing function is separated to 5 stages.
- Setup the project
For building and deploying artifact we will use Gradle with plugins for deployment Lambda functions to AWS Cloud.
First of all we need to setup a Kotlin project — add kotlin-gradle-plugin
With this setup we can compile and test our code written in Kotlin. But for deployment we have to build a fat jar with all dependencies included. With Gradle plugin com.github.johnrengelman.shadow
fat jar creation is done with single command gradle shadowJar
.
With this setup we can compile and test our code written in Kotlin. But for deployment we have to build a fat jar with all dependencies included. With Gradle plugin com.github.johnrengelman.shadow
fat jar creation is done with single command gradle shadowJar
.
Basically this is enough for starting development and testing our application. We can create a fat jar and deploy it to AWS Lambda manually. But this solution is error prone and requires developer’s time, so we can setup deploy with Gradle script to get rid of manual work. It requires two additional plugins jp.classmethod.aws
and jp.classmethod.aws.lambda
. Tasks for deployment and function invocation are easy to configure.
2. Create function
For this example we will create a simple function. It will be responsible for reading data from HTTP request (it requires API Gateway setup) and store data to S3. Off course there is not much functionality in this example, but it suits fine for showing how to bootstrap a project.
Kotlin is a very concise and descriptive programming language. And fits very well for function implementation, because has strong sides like type checks, nullability, but more expressive than Java and does not require complex ceremonies for simple tasks (e.g. data objects creation is done with data classes which already have hashCode(), equals(), toString() methods implemented — unlike Java classes).
For function creation a we have to implement RequestHandler
interface.
handleRequest()
method will execute every time an event received from API Gateway.
3. Create a role for a function
To make the function available for execution we need to create a role with proper permissions and assign this role to a function. We will grant permissions:
- to store data to S3 (required)
- to write logs to Amazon Cloud Watch (nice to have for debugging)
In our example role has name testDemoRole
, if you assign another name for role please update Gradle script accordingly.
4. Deploy function
For function deployment we have to run Gradle task deployFunction — command — gradle deployFunction
. Yes, it’s very simple.
5. Testing
Now we are ready for testing function. First option is to invoke function with AWS console. Log in to AWS console, in Lambda dashboard you can pick newly created function (name — lambda-kotlin-java
) and test it.
We have to configure test event in the console based on API Gateway AWS Proxy template. In body
field we can put data to save on S3.
4. Setup API Gateway
Direct function invocation often used for communication with Lambda, but more common approach is to expose HTTP endpoint for communication. API Gateway for the rescue!
We need to create new API in API Gateway, create resource, create method and connect method with our new Lambda. Don’t forget to mark Use Lambda Proxy integration flag for receiving full HTTP request, not just body.
While crating you will be asked if you grant permission to API Gateway to invoke Lambda, don’t forget to grant permission to API Gateway to call Lambda. After successful API creation we can test API GW integration.
If everything is setup correctly we will have response code 200-OK and new file created in S3 bucket.
After testing we should deploy API and AWS will provide an URL for calling API.
5. Test setting
So at last we can test full integration of our simple serverless application.
For this we should make HTTP call to API Gateway (for example with Postman) and check if file with proper content exists on S3.
Summary:
In this article we’ve built simplest serverless application. We used:
- Gradle for creating artifact to deploy to AWS Lambda, deployment and Lambda invocation
- AWS lambda for processing based Java platform
- Kotlin for internal lambda logic
- API Gateway as gateway to Lambda and S3 as file storage
Additional, but important information
I’m sure during testing Lambda you’ve noticed first call takes much more time than subsequent calls — this is called cold start and it can be quite big.
In my measurements with 512MB of RAM and function we’ve just build, cold start usually took more than 8 second.
To address this issue we will write Lambda function using Kotlin, but deploy it on Node.js platform. See you in next article.