Skip to content

Setting up a Lambda function

Defining a handler

Every AWS Lambda can essentially be written as a regular (async) JavaScript function.

Make sure it is exported like this:

ts
export const handler = async function () {
    // ...
};

Choosing a Lambda integration

In most cases, you will need to decide on a specific Lambda integration. Examples include scheduled events, REST APIs, or handling SQS events.

Depending on the integration you choose, the handler function will accept an additional event parameter and will need to return a specific result. To ensure the parameters and return values are correctly typed, you can use the utilities provided by @backpack/aws-lambda.

For example, with REST integration:

REST integration

ts
import { 
defineRestLambda
} from "@backpack/aws-lambda";
export const
handler
=
defineRestLambda
(async function(
event
) {
return {
statusCode
: 200,
body
: "Hello world!" };
});

Or, with SQS integration:

SQS integration

ts
import { 
defineSqsLambda
} from "@backpack/aws-lambda";
export const
handler
=
defineSqsLambda
(async function(
event
) {
// ... });

Check out @backpack/aws-lambda to learn more.

Object-oriented approach

When your serverless app grows larger, it might be useful to adopt an object-oriented approach.

This enables you to leverage inversion of control with constructor injection, making it suitable for dependency injection frameworks.

ts
// on cold start, bootstrap a new instance (e.g. with a DI framework)
const helloWorldLambda = new HelloWorldLambda(/* ... */);

export const handler = defineRestLambda((event) => {
  // delegate the event to your class instance
  return helloWorldLambda.handle(event);
});
ts
export class HelloWorldLambda {
  constructor(private readonly helloService: HelloService) {}

  public async handle(event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> {
    // ...

    return { statusCode: 200, body: "Hello world!" };
  }
}

Read more about dependency injection.

Adding a CDK construct

To deploy your code to AWS Lambda, you will need to define a CDK construct for it.

Our recommendation is to use the NodeJsFunction construct from aws-cdk-lib/aws-lambda-nodejs, which leverages esbuild to bundle the code of your Lambda.

Ensure the entry option points to the file where your handler function is exported:

ts
import { 
Stack
, StackProps } from "aws-cdk-lib";
import {
Construct
} from "constructs";
import {
Runtime
} from "aws-cdk-lib/aws-lambda";
import {
NodejsFunction
,
OutputFormat
} from "aws-cdk-lib/aws-lambda-nodejs";
import * as
path
from "node:path";
export class
AppStack
extends
Stack
{
constructor(
scope
:
Construct
,
id
: string,
props
?: StackProps) {
super(
scope
,
id
,
props
);
new
NodejsFunction
(this, "MyLambda", {
// 👇 your lambda entry point
entry
:
path
.
join
(import.meta.
dirname
, "../lambda/hello.ts"),
handler
: "handler",
bundling
: {
format
:
OutputFormat
.
ESM
},
runtime
:
Runtime
.
NODEJS_22_X
}); } }

Recommended settings for this construct can be found on our CDK snippet page.

Deploying with CDK

Now use the CDK CLI to deploy your Lambda to your preferred environment:

bash
npx cdk deploy -c config=dev

After a successful deployment, you can trigger your Lambda from the AWS console.