A few months ago I inherited a Kotlin project. It was an unfinished prototype and all I had to do was wrap it up and deploy.
How hard can it be?
The time has come for me to learn Kotlin. Because reasons
β Swizec Teller (@Swizec) March 5, 2019
First surprise: It takes 700MB of space just to install the language. No IDE or anything.
node_modules ain't got nothing on this
Weeks passed. Even months.
Every time I touched the project, it broke. Nothing worked. Wouldn't run on my machine, wouldn't read API requests, couldn't get tests working, if I changed some code I broke it all.
That's when I realized Learning a new field is super hard π
Serverless Handbook for Frontend Engineers βΒ free chapter
Dive modern backend. Understand any backend.
Serverless Handbook taught me high-leveled topics. I don't like recipe courses and these chapters helped me to feel like I'm not a total noob anymore.
The hand-drawn diagrams and high-leveled descriptions gave me the feeling that I don't have any critical "knowledge gaps" anymore.
~ Marek C, engineer
Start with a free chapter and email crash course β€οΈ
Tried to look for help online and ... nothing. The Kotlin community just doesn't seem to exist. There's no gaggle of blogs, no quality courses, there's a few books but everything is for Android.
I'm using Kotlin for the backend damn it, why do I feel so alone?
With no community to be found there's only one conclusion π I'm forcing Kotlin to do something it doesn't want to do. Or Kotlin is weird and on its way out.
Hell, it was easier to find LOLCODE resources for that LOLCODE-to-JavaScript compiler the other day ...
So I said screw it and got the whole project working in TypeScript in 3 days. βοΈ
Why Kotlin? Why TypeScript?
A good question at this point: Why did we even try Kotlin in the first place?
There's a lot of backstory, but it's all about solving these problems π
- we have a Ruby on Rails backend
- it is slow
- parts of the system are struggling under load
- dynamic typing leads to bugs
We wanted to extract the most impacted subsystem. Build it so that it's fast, reliable, and easy for many developers to work with. And isolated from the rest of our monolith.
You can get speed and reliability with AWS Lambdas. You can get type safety with Java. And Java is a very popular language on the backend.
But Java is hard to use and annoying to write.
Kotlin seemed like a great alternative. Runs on the Java Virtual Machine (JVM), interops with Java, and supports many modern functional idioms. Plus it's fast because the JVM is fast.
Except nobody on the team knows Kotlin.
π
But we're smart, we can learn this! And we sort of did.
Until both the person leading the lets-move-to-JVM charge left the company and his I-love-doing-backend protege left us for a career at Google.
Backend people are a special breed, they all seem to love Java and Java-like things so much.
So here I was with this unfinished prototype, no skills in Kotlin, a deep seated distrust of all things Java from college, and an open deadline. Get it working when you can, nothing's on fire right now.
I tried. I did my best. I gave up.
TypeScript!
TypeScript solves our problems, works great with AWS Lambdas, and the whole team knows at least JavaScript.
So I finally forced myself to write some TypeScript for real and I don't hate it. π€¨
β Swizec Teller (@Swizec) May 25, 2019
Greenfield backend project so I was able to avoid `any` like the plague. That helped a bunch in making TS make sense.
Here's things I liked and things I didn't π
TypeScript with AWS Lambda π
- super fast because your code is small
- faster cold start times than Kotlin
- type safety for robustness
You see the thing with AWS Lambda is that you are charged for time. Faster is cheaper, and while JVM functions run faster, node functions start faster.
Our functions are small so runtimes are small. But those cold starts can add up since most Lambda calls are cold. It's a new computer almost every time :)
Engineering is all about tradeoffs
How to use TypeScript for AWS Lambdas
So how do you use TypeScript to write an AWS Lambda function?
Let's write a Hello World
function. I'm extracting this from my real code and haven't tested it. Think of this code as a guide, not a copypasta.
You start by installing the TypeScript compiler. You'll need node support too.
$ npm install -g typescript ts-node
You can now write TypeScript programs and compile them with tsc
so node can run them. Yes you'll need to compile every time before running.
But you already do that for your frontend code anyway :)
You're also going to need the Serverless framework.
$ npm install -g serverless
At this point it's a good idea to open a new terminal window so the new CLI commands register.
Oh and you should setup serverless AWS credentials. It's a little tedious, but you only gotta do it once for all your projects.
tsconfig.json
Before you can seamlessly compile the whole project, you need to configure TypeScript. I copypasta'd this JSON from a blogpost and it works great. Sensible defaults I'd say π
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"outDir": "./dist",
"strict": true,
"baseUrl": "./",
"typeRoots": [
"node_modules/@types"
],
"types": [
"node"
],
"esModuleInterop": true,
"inlineSourceMap": true
}
}
This tells the TypeScript compiler that you're targeting es2017
β the latest JavaScript standard supported by Node 8.10, which is the latest Node that AWS supports. You're using commonjs
modules, writing compiled files to ./dist
and so on.
tsconfig.json supports many options but you aren't likely to need them. At least not at first.
The package.json
Next we'll need a package.json file with some scripts. These will help you build and deploy your code.
{
"name": "hello-world-lambda",
"scripts": {
"build": "tsc",
"deploy": "npm run build && sls deploy"
}
}
We run tsc
to build the project, and sls deploy
to deploy. Adding the build step to your deploy
script makes it less likely that you'll forget to build before deploying.
Always important to deploy the latest code. Gets very frustrating if you don't π
serverless.yml
We use serverless.yml
to configure the Serverless framework. Using this file means you:
- never have to deal with the UI on AWS (or Azure or whatever)
- keep your system architecture in source control
- can reliably build the same server environment every time
Might seem weird at first, but once you get used to all your infrastructure being part of your code ... wow. It's like a whole new world.
Our Hello World
example doesn't need much π
service: hello-world
provider:
name: aws
runtime: nodejs8.10
stage: dev
functions:
hello:
handler: dist/hello.handler
events:
- http:
path: hello
method: GET
cors: true
With that you've configured:
- an AWS Lambda function called
hello
- an APIGateway to proxy API requests
- a CloudWatch setup for any logs
Yep. All that in those few lines of Yaml. Once you deploy Serverless will give you the URL for your hello function.
But first you gotta write it
The hello function β src/hello.ts
Before you write the function, there's a couple dependencies I'd recommend. They make TypeScript work smoother with node and AWS.
$ npm install --save @types/aws-lambda @types/node typescript
I'm not sure the typescript
dependency is strictly necessary, but I have it. The two @types
dependencies give you type information for built-in stuff.
Your hello world function looks like this π
// src/hello.ts
import { APIGatewayEvent } from "aws-lambda";
export const handler = async (event: APIGatewayEvent): Promise<any> => {
return {
statusCode: 200,
body: "Hello world"
}
}
And that's it.
You're importing the type definition for the APIGatewayEvent
. That specifies which properties it does and doesn't have, gives you code completion, and helpful tooltips in VS Code.
To make an endpoint, you export a function. Often called handler
but can be anything. You specified the exact name in your serverless.yml earlier (handler: dist/hello.handler
).
This function takes an event
, does whatever it wants, and returns a response with a statusCode
and a body
. 200 means OK
.
You can run npm run deploy
, wait a bit, and voila you've got a URL that says Hello World
π
That's what I love about this new function-as-a-service world. Anyone can build a backend. A good backend. Not just those Java-toting backend weirdos.
Happy Monday β€οΈ,
~Swizec
PS: if you wanna read more about my initial impressions of TypeScript, you should check out this twitter thread
Continue reading about TypeScript for serverless lambda backends π
Semantically similar articles hand-picked by GPT-4
- Modern backend is a JavaScript function
- If you can JavaScript, you can backend
- Your serverless questions, answered
- How serverless beats servers
- Go full-stack in 5min with your first cloud function
Want to dive into serverless? Not sure where to begin?
Serverless Handbook was designed for people like you getting into backend programming.
360 pages, 19 chapters, 6 full projects, hand-drawn diagrams, beautiful chapter art, best-looking cover in tech. βοΈ
Learn how to choose the right database, write cloud functions, think about scalability, gain the architecture mindsets for robust systems, and more.
Leave your email to start with a free chapter and email crash course π
Serverless Handbook for Frontend Engineers βΒ free chapter
Dive modern backend. Understand any backend.
Serverless Handbook taught me high-leveled topics. I don't like recipe courses and these chapters helped me to feel like I'm not a total noob anymore.
The hand-drawn diagrams and high-leveled descriptions gave me the feeling that I don't have any critical "knowledge gaps" anymore.
~ Marek C, engineer
Start with a free chapter and email crash course β€οΈ
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help π swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers π ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are β€οΈ