Serverless application with AWS Lambda and Kotlin. Part 3
Part 3— Improving performance: Kotlin + Node.js+ 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
- Warmup optimization: Writing functions in Kotlin for Node.js platform on AWS Lambda (you are here)
- 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 function on AWS Lambda based on Node.js platform with Kotlin programming language.
In previous chapter we’ve deployed a simple serverless application based on Java platform using Kotlin programming language. The issue was a so called cold start — when first function invocation takes long time — in our case 8 seconds instead of 300 ms in later invocations.
One of the solution recommended in the tech blogs to address this issue is to use dynamic typed languages (Python, JavaScript) instead of statically typed. But we still want to use Kotlin and it’s cool features. And actually type checking provided by Kotlin during development helps a lot.
There is a possibility to compile Kotlin code to JavaScript. With KotlinJS we will try to make startup faster.
The idea of application is the same as in previous article — to receive data from the API Gateway and to store it to S3 bucket. We still want an deployment configured in Gradle.
All source code can be downloaded from Github.
- Setup the project
In Java example we’ve built a fat jar to include all runtime dependencies to deployable artifact. In this example we will go similar way and create deployable artifact (zip archive) with JS libraries included.
To setup gradle compilation to JS step we need to include kotlin2js
gradle plugin, it adds gradle tasks compileKotlin2Js
, compileTestKotlin2Js
. Configuration is quite simple.
Installing dependencies is important part in project setup. First we need to include kotlin-stdlib-js
dependency which provides standard Kotlin features in JS environment.
Second we need to provide JS runtime dependencies. In package.json
we specify them.
And in gradle script we will create a task to install dependencies (requires com.moowork.node
plugin).
Packaging is made with zip task from gradle and deployment with aws-gradle plugin.
2. Lambda Code
Our intention to preserve code with business logic most similar to the code in implementation for Java platform to make transition from Java to Node.js as seamless as possible. It requires encapsulation of interaction of Kotlin Code and JS. Task may become difficult when there are many libraries, but in our case it’s only AWS S3 SDK and small number of standard JS functions (require
and process.env
). In other aspects switching to KotlinJS won’t be so difficult for Java/Kotlin developers.
Calls to JS functions encapsulated in specific module, business logic should not be couples with platform specific functions.
Important note: I do not say that transfer from Kotlin to KotlinJS will be seamless, you have learn KotlinJS specific concepts like dynamic types, external modifier, kotlin-js standard library, etc.
To implement function we have to create function which receives request object, context and callback parameters and mark it with annotation @JsName
to make available for import.
AWS Lambda requires specification of entrypoint to the function. Let’s create simple JS file and specify entrypoint.
That’s it we’ve setup a project which can import JS dependencies, build and deploy function to AWS.
For development it is also good to have testing features set up.
3. Testing
JetBrains provides a library org.jetbrains.kotlin:kotlin-test-js
for testing in KotlinJS. As you can see in an example test are very similar to JUnit tests which again simplifies development for Java/Kotlin developers.
For testing we need to properly setup compilation, packaging and running test framework (Jasmin in our example).
We’ve setup an environment ready for development, testing and deployment.
Some performance metrics
As you can see in our measurements function running on Node.js platform has much less start time comparing to Java platform. But this improvement comes with a price — for Java/Kotlin developer writing code in Kotlin and compile to JS requires some knowledge of the platform.
Summary:
- With this example we have ready for development pipeline and with single command
gradle deployFunction
full build/test/deploy lifecycle is covered - Transition from Java to Node.js platform shouldn’t take much efforts due to encapsulation of JS code
- Out measurements show smaller warmup time on Node.js comparing to Java platform with small changes in code responsible for business logic written in Kotlin in both examples