Skip to content

Dynamo

Reference doc for the `sst.aws.Dynamo` component.

The Dynamo component lets you add an Amazon DynamoDB table to your app.

Minimal example

const table = new sst.aws.Dynamo("MyTable", {
fields: {
userId: "string",
noteId: "string"
},
primaryIndex: { hashKey: "userId", rangeKey: "noteId" }
});

Add a global index

Optionally add a global index to the table.

new sst.aws.Dynamo("MyTable", {
fields: {
userId: "string",
noteId: "string",
createdAt: "number",
},
primaryIndex: { hashKey: "userId", rangeKey: "noteId" },
globalIndexes: {
CreatedAtIndex: { hashKey: "userId", rangeKey: "createdAt" }
}
});

Add a local index

Optionally add a local index to the table.

new sst.aws.Dynamo("MyTable", {
fields: {
userId: "string",
noteId: "string",
createdAt: "number",
},
primaryIndex: { hashKey: "userId", rangeKey: "noteId" },
localIndexes: {
CreatedAtIndex: { rangeKey: "createdAt" }
}
});

Subscribe to a DynamoDB Stream

To subscribe to a DynamoDB Stream, start by enabling it.

const table = new sst.aws.Dynamo("MyTable", {
fields: {
userId: "string",
noteId: "string"
},
primaryIndex: { hashKey: "userId", rangeKey: "noteId" },
stream: "new-and-old-images"
});

Then, subscribing to it.

table.subscribe("src/subscriber.handler");

You can link the table to other resources, like a function or your Next.js app.

new sst.aws.Nextjs("MyWeb", {
link: [table]
});

Once linked, you can query the table through your app.

app/page.tsx
import { Resource } from "sst";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, QueryCommand } from "@aws-sdk/lib-dynamodb";
const client = DynamoDBDocumentClient.from(new DynamoDBClient({}));
await client.send(new QueryCommand({
TableName: Resource.MyTable.name,
KeyConditionExpression: "userId = :userId",
ExpressionAttributeValues: {
":userId": "my-user-id"
}
}));

Constructor

new Dynamo(name, args, opts?)

Parameters

DynamoArgs

fields

Type Input<Record<string, string | number | binary>>

An object defining the fields of the table that’ll be used to create indexes. The key is the name of the field and the value is the type.

While you can have fields field types other than string, number, and binary; you can only use these types for your indexes.

{
fields: {
userId: "string",
noteId: "string"
}
}

globalIndexes?

Type Input<Record<string, Input<Object>>>

Configure the table’s global secondary indexes.

You can have up to 20 global secondary indexes per table. And each global secondary index should have a unique name.

{
globalIndexes: {
CreatedAtIndex: { hashKey: "userId", rangeKey: "createdAt" }
}
}

globalIndexes[].hashKey

Type Input<string>

The hash key field of the index. This field needs to be defined in the fields.

globalIndexes[].rangeKey?

Type Input<string>

The range key field of the index. This field needs to be defined in the fields.

localIndexes?

Type Input<Record<string, Input<Object>>>

Configure the table’s local secondary indexes.

Unlike global indexes, local indexes use the same hashKey as the primaryIndex of the table.

You can have up to 5 local secondary indexes per table. And each local secondary index should have a unique name.

{
localIndexes: {
CreatedAtIndex: { rangeKey: "createdAt" }
}
}

localIndexes[].rangeKey

Type Input<string>

The range key field of the index. This field needs to be defined in the fields.

primaryIndex

Type Input<Object>

Define the table’s primary index. You can only have one primary index.

{
primaryIndex: { hashKey: "userId", rangeKey: "noteId" }
}

primaryIndex.hashKey

Type Input<string>

The hash key field of the index. This field needs to be defined in the fields.

primaryIndex.rangeKey?

Type Input<string>

The hash key field of the index. This field needs to be defined in the fields.

stream?

Type Input<keys-only | new-image | old-image | new-and-old-images>

Default Not enabled

Enable DynamoDB Streams for the table.

When an item in the table is modified, the stream captures the information and sends it to your subscriber function.

You can configure what will be written to the stream:

  • new-image: The entire item after it was modified.
  • old-image: The entire item before it was modified.
  • new-and-old-images: Both the new and the old items. A good default to use since it contains all the data.
  • keys-only: Only the keys of the fields of the modified items. If you are worried about the costs, you can use this since it stores the least amount of data.
{
stream: "new-and-old-images"
}

transform?

Type Object

Transform how this component creates its underlying resources.

transform.table?

Type TableArgs | (args: TableArgs => void)

Transform the DynamoDB Table resource.

ttl?

Type Input<string>

The field of the table to store the Time to Live (TTL) timestamp in. This field should be of type number. When the TTL timestamp is reached, the item will be deleted.

Learn more about Time to Live (TTL).

{
ttl: "expireAt",
}

Properties

arn

Type Output<string>

The ARN of the DynamoDB Table.

name

Type Output<string>

The name of the DynamoDB Table.

nodes

Type Object

The underlying resources this component creates.

nodes.table

Type Output<Table>

The Amazon DynamoDB Table.

SDK

The following are accessible through the SDK at runtime.

name

Type string

The name of the DynamoDB Table.

Methods

subscribe

subscribe(subscriber, args?)

Parameters

Returns Output<DynamoLambdaSubscriber>

Subscribe to the DynamoDB Stream of this table.

table.subscribe("src/subscriber.handler");

Add a filter to the subscription.

table.subscribe("src/subscriber.handler", {
filters: [
{
dynamodb: {
Keys: {
CustomerName: {
S: ["AnyCompany Industries"]
}
}
}
}
]
});

Customize the subscriber function.

table.subscribe({
handler: "src/subscriber.handler",
timeout: "60 seconds"
});

static subscribe

Dynamo.subscribe(streamArn, subscriber, args?)

Parameters

  • streamArn Input<string>

    The ARN of the DynamoDB Stream to subscribe to.
  • subscriber string | FunctionArgs

    The function that’ll be notified.
  • args? DynamoSubscriberArgs

    Configure the subscription.

Returns Output<DynamoLambdaSubscriber>

Subscribe to the DynamoDB stream of a table that was not created in your app.

For example, let’s say you have a DynamoDB stream ARN of an existing table.

const streamArn = "arn:aws:dynamodb:us-east-1:123456789012:table/MyTable/stream/2024-02-25T23:17:55.264";

You can subscribe to it by passing in the ARN.

sst.aws.Dynamo.subscribe(streamArn, "src/subscriber.handler");

Add a filter to the subscription.

sst.aws.Dynamo.subscribe(streamArn, "src/subscriber.handler", {
filters: [
{
dynamodb: {
Keys: {
CustomerName: {
S: ["AnyCompany Industries"]
}
}
}
}
]
});

Customize the subscriber function.

sst.aws.Dynamo.subscribe(streamArn, {
handler: "src/subscriber.handler",
timeout: "60 seconds"
});

DynamoSubscriberArgs

filters?

Type Input<Input<Record<string, any>>[]>

Filter the records processed by the subscriber function.

You can pass in up to 5 different filter policies. These will logically ORed together. Meaning that if any single policy matches, the record will be processed.

For example, if your DynamoDB table’s stream contains the follow record.

{
eventID: "1",
eventVersion: "1.0",
dynamodb: {
ApproximateCreationDateTime: "1678831218.0",
Keys: {
CustomerName: {
"S": "AnyCompany Industries"
},
NewImage: {
AccountManager: {
S: "Pat Candella"
},
PaymentTerms: {
S: "60 days"
},
CustomerName: {
S: "AnyCompany Industries"
}
},
SequenceNumber: "111",
SizeBytes: 26,
StreamViewType: "NEW_IMAGE"
}
}
}

To process only those records where the CustomerName is AnyCompany Industries.

{
filters: [
{
dynamodb: {
Keys: {
CustomerName: {
S: ["AnyCompany Industries"]
}
}
}
}
]
}

transform?

Type Object

Transform how this subscription creates its underlying resources.

transform.eventSourceMapping?

Type EventSourceMappingArgs | (args: EventSourceMappingArgs => void)

Transform the Lambda Event Source Mapping resource.