Rafal WilinskiBlogConsulting

October 15, 2019 / 3 minutes / #AWS #Serverless #Amplify #Typescript

Creating AWS Amplify Functions in Typescript

AWS Amplify gives a great power to the developers. With just a few commands you can unlock true power of Cloud and provision whole APIs, add some Lambda functions and host in on S3 with CloudFront CDN in front of it. However, right now Amplify supports creating only Javascript-powered functions. In this article I'll explain how you can create your functions in Typescript. Moreover, following method should work for other languages such as Kotlin, ReasonML or ClojureScript!

Let's start with creating Amplify project and custom function

    Create base project using React or any other boilerplate generator.

npx create-react-app amplify-typescript-functions

    Initialise Amplify project

amplify init

and proceed through Amplify project creation wizard...

    After you created project, go ahead and add a function with following command

amplify function add

And once again proceed through guided creation process.

    After that you should see a new folder amplify/backend/function/<YOUR FUNCTION NAME> appear in your project structure.

> amplify-typescript-demo/amplify/backend $ tree
.
├── amplify-meta.json
├── awscloudformation
│   └── nested-cloudformation-stack.yml
├── backend-config.json
└── function
    └── amplifytypescriptdemf00d9d47
        ├── amplifytypescriptdemf00d9d47-cloudformation-template.json
        ├── function-parameters.json
        └── src
            ├── event.json
            ├── index.js
            └── package.json

Adding Typescript function

We have our desired function but it's in Javascript and we want to add some types to it. So, go ahead and remove index.js and replace it with index.ts. Paste following code inside:

import { APIGatewayProxyHandler } from 'aws-lambda';
import 'source-map-support/register';

export const handler: APIGatewayProxyHandler = async (event,  _context) => {
  console.log(event);
  return  {
    statusCode:  200,
    body: JSON.stringify({
      message:  'Amplify function in Typescript!',
      input:  event,
    }),
  };
};

Typescript also need some instructions what to do with following code and how to compile it so we'll need tsconfig.json file too. Here's what should be inside:

{
  "compilerOptions":  {
    "lib":  ["es2017"],
    "moduleResolution":  "node",
    "noUnusedLocals":  true,
    "noUnusedParameters":  true,
    "sourceMap":  true,
    "target":  "es2017",
    "outDir":  "lib"
  },
  "exclude":  ["node_modules"]
}

package.json will also need some adjustments:

"dependencies":  {
  "source-map-support": "0.5.10"
},
"devDependencies":  {
  "@types/aws-lambda": "8.10.17",
  "@types/node": "10.12.18"
}

You might also consider adding .gitignore file add exclude all *.js files there.

Putting it all together

Lastly, we need to install typescript as devDependency at the root of our project and tell Amplify what to do with our TS-based function. Fortunately, recently Amplify added Build Options for Functions. With that in mind, we can add following command to package.json:

"scripts":  {
  "amplify:<YOUR_FN_NAME>":  "cd amplify/backend/function/<YOUR_FN_NAME>/src && yarn && tsc ./*.ts"
}

With this little piece, once you execute amplify push following script will be executed and build TS source files before deploying anything.

You can test it locally using amplify function invoke <YOUR_FN_NAME> (make sure it's built first!). Final result is also available as Github Repository here

Following example works really well if number of functions is quite low (because each function converts directly to extra command in package.json and there is no shared code between them. In the upcoming article I'll explore different ways to do that more efficiently, stay tuned!


-- Written by Rafal Wilinski. Founder of Dynobase - Professional GUI Client for DynamoDB


GithubTwitterInstagram