Debugging Node.js Lambda invoked by ApiGateway
Debugging tools are fundamental for our day-to-day work as developers. Running a Lambda inside its original environment, with the ability to add breakpoints on the fly, and to watch variable values change in real-time, could save hours and possibly days of debugging.
My personal opinion is that setting up a good development environment pays off in the long term.
There are some good tutorials out there explaining how to trigger specific Lambda functions via sam local invoke function. These are great for some cases, yet spinning up a server which can be triggered via postman is a different level of ease in my opinion.
After a few unsuccessful Google searches, I’ve finally figured out how to debug a Node.js SAM Lambda, invoked by ApiGateway via Webstorm leveraging real-time breakpoints. Here is a short tutorial of how it can be achieved:
Starting point
You should already have an AWS Lambda application that is wired to ApiGateway via SAM (Cloud formation)
template.yml
Overview: the first resource is a gateway. In this case, it is generated via open-api specification. I’m not going to go over how it is done, and using open-api is optional. The second resource is the Lambda function. CodeUri specifies where the actual javascript code is located, since the Lambda is written in typescript. It means when debugging, breakpoints should be placed in the build folder js code, since that is the code that is executed.
Lambda handler:
When using typescript, before debugging, build your project to generate a js file inside your build folder:
There is already a breakpoint placed on line 6, ready to be triggered, make sure you add one as well.
Before we continue, make sure sam cli and docker are installed on your machine
Now we are going to do the following:
- Spin up a sam server on port 3000 which will listen to incoming requests and route them to a docker container.
- Spin up a docker container on port 5858 which will receive Lambda triggers. Then attach Webstorm to this container to control execution.
All of this is done via a single command:
$ sam local start-api -d 5858
Output:
Now if you run $ docker ps you will notice there is no container on port 5858 as I previously said there would be. This is because we didn’t trigger a request yet. We can do it via postman:
After executing the request via postman the request should be stuck on “sending request”. Go and check out your terminal:
The server running on port 3000 detected a request and mounted the Lambda function with a docker container on port 5858.
$ docker ps
Awesome, now the only thing we are missing is attaching WebStorm to the container running on port 5858:
Immediately after hitting the “debug” button, your breakpoint will be triggered:
Cool ha? 🕺🏻
If you open your terminal, you will notice that the container was attached to the Webstrom process:
I hope this tutorial helps a few serverless developers with debugging.
Please let me know if it helped, or you found it useful, by hitting the “Clap!” button. 👏
Cheers!
Edit:
Some have requested configuration for the case of VSCode:
{
"type": "node",
"request": "attach",
"name": "Attach to SAM CLI",
"address": "localhost",
"port": 5858,
"localRoot": "${workspaceRoot}/build",
"outFiles": ["${workspaceFolder}/build/**/*.js"],
"remoteRoot": "/var/task",
"protocol": "inspector",
"stopOnEntry": false
}