How to Locally Test Amplify Serverless ExpressJS Functions

When you add a new lambda function using the Serverless ExpressJS template in Amplify, it can be difficult to initially test the basics of your function. Amplify has a built-in mock command, but it has several drawbacks.

In this short guide I'll show you how to set up your function and how to update your package.json to quickly test your function locally, without interfering with your Amplify deployment.

I'm going to assume that you've got a project set up with AWS Amplify and are familiar with the basics of the Amplify CLI, and that you're working with NodeJS functions.

Let's start by adding our function:

$ amplify function add
? Select which capability you want to add: (Use arrow keys)
> Lambda function (serverless function)
  Lambda layer (shared code & resource used across functions)
? Provide an AWS Lambda function name: myNewApi
? Choose the runtime that you want to use: (Use arrow keys)
  .NET Core 3.1
  Go
  Java
> NodeJS
  Python
? Choose the function template that you want to use:
  CRUD function for DynamoDB (Integration with API Gateway)
  Hello World
  Lambda trigger
> Serverless ExpressJS function (Integration with API Gateway)

Available advanced settings:
- Resource access permissions
- Scheduled recurring invocation
- Lambda layers configuration

? Do you want to configure advanced settings? (y/N) n
? Do you want to edit the local lambda function now? (Y/n) n
Successfully added resource myNewApi locally.

Now that you've added your function, let's add the API Gateway and connect it to our new function:

$amplify add api
? Please select from one of the below mentioned services:
  GraphQL
> REST
? Provide a friendly name for your resource to be used as a label for this category in the project: myNewApi
? Provide a path (e.g., /book/{isbn}): /
? Choose a Lambda source
  Create a new Lambda function
> Use a Lambda function already added in the current Amplify project
? Choose the Lambda function to invoke by this path
> myNewApi
   (other lambda functions)
(Move up and down to reveal more choices)
? Restrict API access (Y/n) n
? Do you want to add another path? (y/N) n
Successfully added resource myNewApi locally

Note that I definitely recommend restricting API access right away if you need it, because it can be a pain to update it later on.

Now that we've got our function and API created, let's go ahead and push that to amplify:

$ amplify push

With our function deployed, we will now set it up for local development. Navigate to your function directory, and install nodemon as a dev dependency:

$ cd amplify/backend/function/myNewApi
npm install --save-dev nodemon

Now, we need to add a directive to our package.json to let us easily run nodemon from the command line:

...
  "scripts": {
    "start:local": "nodemon app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
...

Now, in order to locally test your serverless function, simply run:

npm run start:local

This won't interfere with the configuration Amplify sets up for you automatically, so you can quickly develop your function locally, and when you're ready for staging/production, push it live with amplify push.

Happy coding!