Skip to main content

Clients

Import from sst/node in your Lambda functions.

Use the typesafe Node.js client in your functions to connect to your infrastructure.


About

The SST Node.js client gives your Lambda functions typesafe access to the infrastructure in your app.

So for example, you can create an S3 bucket and bind it to your API.

stacks/MyStack.ts
const bucket = new Bucket(stack, "myFiles");

api.bind([bucket]);

And in your Lambda function you can access that bucket through the SST Node client.

packages/functions/lambda.ts
import { Bucket } from "sst/node/bucket";

await s3.send(
new PutObjectCommand({
Bucket: Bucket.myFiles.bucketName,
Key: "greeting.txt",
Body: "Hello world!",
})
);

The Node client also gives you handlers that wrap around your Lambda function with proper typesafety.


Installation

The SST Node client is available through the sst npm package.

npm install sst --save-exact

If you are using our starters, the sst package should already be installed.


Usage

You can then import a specific module from the client through sst/node/*.

import { Bucket } from "sst/node/bucket";

Exports

The sst/node package is made up of a collection of modules. Like the sst/node/api, sst/node/bucket, etc. These modules have the following types of exports.


Properties

The properties in each module helps you access the resources that are bound to the function.

For exmaple, you can access the bucket name in your function by importing Bucket from the sst/node/bucket module:

import { Bucket } from "sst/node/bucket";

console.log(Bucket.myFiles.bucketName);
info

Due to the use of top-level await, your functions need to be bundled in the esm format. If you created your app using create-sst, the bundle format is likely already set to esm. Here's how to set the Function bundle format.


Handlers

The handlers in each module is a function that can wrap around Lambda function handlers. Here's an example of the API handler.

import { ApiHandler } from "sst/node/api";

export const handler = ApiHandler((event) => {
// ...
});
caution

Handlers are being actively worked on and are subject to change.

Each handler has a specific purpose but they share a couple of things in common:

  1. Provide proper typesafety.
  2. They also initialize SST's context system to power our Hooks.

Hooks

The hooks in each module are functions that you can call anywhere in your application code. It has access to things that are specific to the current invocation. This avoids having to pass things through multiple function calls down to our domain code.

caution

Hooks are being actively worked on and are subject to change.

For example, you can call the useSession hook to get access to the current user session in APIs that need authentication.

import { useSession } from "sst/node/auth";

const session = useSession();

if (session.type === "user") {
console.log(session.properties.userID);
}

Behind the scenes, Hooks are powered by a SST's context system. Handlers like the GraphQLHandler and the AuthHandler create a global variable that keeps track of the "context" for the current request. This context object gets reset on every invocation.

Hooks are an alternative to middleware solutions like Middy. They provide better typesafety and will be familiar to developers that've used Hooks in frontend frameworks.


Others

Some of the modules also export types that can be used to define payloads for function calls. For example, the job exports JobTypes.

The job also exports a method to run a job.


Language support

Currently the client only supports JavaScript and TypeScript. If you are looking to add support for other languages, here's a basic guide to set the ball rolling. If you need help, feel free to message us in Discord.

How the client works

For every bound resource, an environment variable is added to the Function. The environment variable naming convention is:

SST_{construct}_{prop}_{id}

For example, if you bind a Bucket:

const myBucket = new Bucket(stack, "myBucket");
myFn.bind([myBucket]);

An environment variable called SST_Bucket_bucketName_myBucket is added, containing the bucket name as its value. The client should provide a convenient accessor to this value. In the Node client, the accessor pattern is:

import { Bucket } from "sst/node/bucket";
console.log(Bucket.myBucket.bucketName);

Fetching from SSM

Sometimes the value in the environment variable might be

__FETCH_FROM_SSM__

In this case, you'll need to fetch the value from SSM Parameter Store at path:

/sst/{app}/{stage}/{construct}/{id}/{prop}

The {app} and {stage} segments can be obtained from the environment variables SST_APP and SST_STAGE. You should batch SSM calls for efficiency.

Referencing SSM values

If the environment variable value is

__FETCH_FROM_SECRET__:{secret}

You must first resolve the Secret's value and assign it to the variable.


Usage in tests

To access the properties in your tests, you'll need to wrap your tests with the sst bind command.

sst bind "vitest run"

This allows the sst/node package to work as if it was running inside a Lambda function.

Read more about testing and learn about the sst bind CLI.