How to use Typescript with AWS Amplify Function
Compile your typescript function and lint it before pushing it. Don't push useless library to the cloud and keep your function as small as it should be.
Install and Configure AWS Amplify
First, follow the instructions on this page to set up amplify:
Init your Amplify project
npm init private
amplify init
Then choose as below (or according to your need)
Make VS Code ready for Typescript
If you don’t use VS Code, you can skip this.
Add Settings and Extensions for VS Code
mkdir .vscodecurl -o .vscode/extensions.json https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.vscode_extensions.jsoncurl -o .vscode/settings.json https://gist.githubusercontent.com/vdelacou/eeb8931e510218dac1464d3cd592722c/raw/868452b13dd73bf0f9f7b4c5e76143f02583647c/.vscode_settings.json
Add Prettier and Editorconfig configuration
curl -o .prettierrc https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.prettierrccurl -o .prettierignore https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.prettierignorecurl -o .editorconfig https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.editorconfig
As it’s not the topic here, I let you check the files at their gist adresses.
Create your first function
amplify add function
We create a new function named concatenate
as below:
Setup our Typescript Function
First, go the function folder and delete index.js
and package.json
cd amplify/backend/function/concatenate/srcrm index.js package.json
Create a ts
folder, where we will put our typescript code
cd ..
mkdir ts
cd ts
Start our typescript project
npm init privatenpm install aws-lambda aws-sdknpm install --save-dev typescript @types/node @types/aws-lambda eslint@6.8.0 eslint-plugin-flowtype@3 @typescript-eslint/eslint-plugin@2.31.0 eslint-config-airbnb-base@latest eslint eslint-plugin-import @typescript-eslint/parser@2.31.0 eslint-config-airbnb-typescript prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks@2.5.0
aws-lambda
library do not need to be in prod dependencies as it will be included automatically in our AWS Lambda when deployed.
Add the tsconfig.json
for our function
curl -o tsconfig.json https://gist.githubusercontent.com/vdelacou/eeb8931e510218dac1464d3cd592722c/raw/b689f79c9dea03accb4327b06a16df99448f37f7/tsconfig.json
Then set the configuration for Eslint
curl -o .eslintrc.json https://gist.githubusercontent.com/vdelacou/d6a880059777451a913acd962b8e43a8/raw/.eslintrc.jsoncurl -o .eslintignore https://gist.githubusercontent.com/vdelacou/58484f1c11af70aaa457f4e5c289e893/raw/.eslintignore
Time to code our first function
touch index.ts
A Lambda function takes an event in input and gives a result. The input event can be everything, for example, an S3 event, a Cognito event, a DynamoDB event, or anything you want. Lambda is often associated with Api Gateway Event, so it becomes confusing to use a lambda without calling an API, but a lambda it's just a function.
We will make an easy function. As the default event given by the generated Hello World
function is :
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
We will just make a function that takes this event and return a string with the key concatenate. Just copy this to your index.ts
file
import { Callback, Context, Handler } from 'aws-lambda';interface TriggerEvent {
key1: string;
key2: string;
key3: string;
}export const handler: Handler<TriggerEvent, string> = (event: TriggerEvent, context: Context, callback: Callback<string>) => {
const concatKey = `${event.key1} ${event.key2} ${event.key3}`;
callback(null, concatKey);
};
Try our function locally
In your ts
folder add this to your package.json
...
"scripts": {
"tsc": "npm run lint && tsc",
"lint": "eslint . --ext .ts"
}
...
And then launch:
npm run tsc
You can now see in the js
folder the compiled fileindex.js
To launch locally
amplify mock function concatenate
Choose the file src/event.json
when asked and then you can see the result
Publish your function
At the root
folder add this to your package.json
...
"scripts": {
"amplify:concatenate": "cd amplify/backend/function/concatenate/ts && npm install && npm run tsc && cd -"
},
...
Then push it:
amplify push
You can now open the console
amplify console
Find "Functions" and then click on "View on Lambda"
As you can see there is only the index.js
and event.json
publish to the lambda, so we have kept it simple and very light.
You can now use the content of event.json
to test your function "online" by selecting "configure test event" at the top right
Function with dependencies
We will try to make a simple function which uses i18n
to return a translation
amplify add function
Choose the function name : translate
then do exactly the same as above with the concatenate function
In the folder src
do the following:
npm init privatenpm install i18n
Also, change the event.json
to
{
"lang": "fr"
}
Create a folder for the locales and create translations files
mkdir locales
cd locales
echo "{ \"title\": \"Translation\" }" > en.json
echo "{ \"title\": \"Traduction\" }" > fr.json
So now compare to the previous function we also have a package.json
in the src
folder.
Then in the ts
folder we also install the i18n
library:
npm install i18n
npm install --save-dev @types/i18n
Then change the index.ts
to :
import { Callback, Context, Handler } from 'aws-lambda';
import i18n from 'i18n';interface TriggerEvent {
lang: string;
}export const handler: Handler<TriggerEvent, string> = (event: TriggerEvent, context: Context, callback: Callback<string>) => {
// init i18n
i18n.configure({
defaultLocale: 'en',
directory: __dirname + '/locales',
});
// set locale according to event
i18n.setLocale(event.lang); // return the translation
callback(null, i18n.__('title'));
};
Compile locally and test it:
npm run tsc && amplify mock function translate
You should see the result :
You can change the lang in the event.json
to "lang":"en"
and after launch again npm run tsc && amplify mock function translate
you should see:
Publish the function, by adding at the root
folder this to your package.json
...
"scripts": {
...
"amplify:translate": "cd amplify/backend/function/translate/ts && npm install && npm run tsc && cd -"
...
}
...
Then push it:
amplify push
As you can see, now we have package.json
, locales
and node_modules
folders in our lambda, but we kept it small and simple.
Remove and clean all in AWS
amplify delete
BONUS
Hide compile .js files
If you want to hide the file from your VS Code go to .vscode/settings.json
and add the following:
...
"files.exclude": {
"amplify/backend/function/**/*.js": true
},
...
And also add in the src
folder a .gitignore
file with
*.js
Library aws-sdk
If you needaws-sdk
, you can add it to the package.json
in the src
folder in the dev dependencies only, as it will be included automatically in our AWS Lambda when deployed. You don't need to add it in the prod dependencies. In the ts
folder you can also add it in the dev dependencies.