Skip to main content

Topic

caution

This is the SST v1.x Constructs doc. SST v2 is now released. If you are using v2, see the v2 Constructs doc. If you are looking to upgrade to v2, check out the upgrade steps.

The Topic construct is a higher level CDK construct that makes it easy to create a serverless pub/sub service. You can create a topic that has a list of subscribers. And you can publish messages to it from any part of your serverless app.

You can have two types of subscribers; Function subscribers (subscribe with a Lambda function) or Queue subscribers (subscribe with a SQS queue).

This construct makes it easier to define a topic and its subscribers. It also internally connects the subscribers and topic together.

Examples​

Using the minimal config​

import { Topic } from "@serverless-stack/resources";

new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/function1.handler",
subscriber2: "src/function2.handler"
},
});

Configuring subscribers​

Lazily adding subscribers​

Add subscribers after the topic has been created.

const topic = new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/subscriber1.main",
subscriber2: "src/subscriber2.main",
},
});

topic.addSubscribers(this, {
subscriber3: "src/subscriber3.main",
});

Configuring Function subscribers​

Specifying function props for all the subscribers​

You can extend the minimal config, to set some function props and have them apply to all the subscribers.

new Topic(stack, "Topic", {
defaults: {
function: {
timeout: 20,
environment: { tableName: table.tableName },
permissions: [table],
},
},
subscribers: {
subscriber1: "src/subscriber1.main",
subscriber2: "src/subscriber2.main",
},
});

Configuring an individual subscriber​

Configure each Lambda function separately.

new Topic(stack, "Topic", {
subscribers: {
subscriber: {
function: {
srcPath: "src/",
handler: "subscriber1.main",
environment: { tableName: table.tableName },
permissions: [table],
},
},
},
});

Note that, you can set the defaultFunctionProps while using the function per subscriber. The function will just override the defaultFunctionProps. Except for the environment, the layers, and the permissions properties, that will be merged.

new Topic(stack, "Topic", {
defaults: {
function: {
timeout: 20,
environment: { tableName: table.tableName },
permissions: [table],
},
},
subscribers: {
subscriber1: {
function: {
handler: "subscriber1.main",
timeout: 10,
environment: { bucketName: bucket.bucketName },
permissions: [bucket],
},
},
subscriber2: "subscriber2.main",
},
});

So in the above example, the subscriber1 function doesn't use the timeout that is set in the defaultFunctionProps. It'll instead use the one that is defined in the function definition (10 seconds). And the function will have both the tableName and the bucketName environment variables set; as well as permissions to both the table and the bucket.

Giving the subscribers some permissions​

Allow the subscriber functions to access S3.

const topic = new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/subscriber1.main",
subscriber2: "src/subscriber2.main",
},
});

topic.attachPermissions(["s3"]);

Giving a specific subscriber some permissions​

Allow the first subscriber function to access S3.

const topic = new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/subscriber1.main",
subscriber2: "src/subscriber2.main",
},
});

topic.attachPermissionsToSubscriber("subscriber1", ["s3"]);

Configuring the subscription​

Configure the internally created CDK Subscription.

import { SubscriptionFilter } from "aws-cdk-lib/aws-sns";

new Topic(stack, "Topic", {
subscribers: {
subscriber1: {
function: "src/subscriber1.main",
cdk: {
subscription: {
filterPolicy: {
color: SubscriptionFilter.stringFilter({
allowlist: ["red"],
}),
},
},
},
},
},
});

Configuring Queue subscribers​

Specifying the Queue directly​

You can directly pass in an instance of the Queue construct.

const myQueue = new Queue(this, "MyQueue");

new Topic(stack, "Topic", {
subscribers: {
subscriber: myQueue
},
});

Configuring the subscription​

Configure the internally created CDK Subscription.

import { SubscriptionFilter } from "aws-cdk-lib/aws-sns";

const myQueue = new Queue(this, "MyQueue");

new Topic(stack, "Topic", {
subscribers: {
subscriber: {
queue: myQueue,
cdk: {
subscription: {
filterPolicy: {
color: SubscriptionFilter.stringFilter({
allowlist: ["red"],
}),
},
},
},
},
},
});

FIFO topic​

new Topic(stack, "Topic", {
cdk: {
topic: {
fifo: true,
},
},
});

Note that as of June 2022, FIFO Topic does not support Lambda subscription.

Advanced examples​

Configuring the SNS Topic​

Configure the internally created CDK Topic instance.

new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/subscriber1.main",
subscriber2: "src/subscriber2.main",
},
cdk: {
topic: {
topicName: "my-topic",
},
},
});

Importing an existing Topic​

Override the internally created CDK Topic instance.

import * as sns from "aws-cdk-lib/aws-sns";

new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/subscriber1.main",
subscriber2: "src/subscriber2.main",
},
cdk: {
topic: sns.Topic.fromTopicArn(this, "MySnsTopic", topicArn),
},
});

Constructor​

new Topic(scope, id, props)

Parameters

TopicProps​

defaults.function?​

Type : FunctionProps

The default function props to be applied to all the consumers in the Topic. The environment, permissions and layers properties will be merged with per route definitions if they are defined.

new Topic(stack, "Topic", {
defaults: {
function: {
timeout: 20,
}
},
});

subscribers?​

Type : Record<string, string | Function | Queue | TopicQueueSubscriberProps | TopicFunctionSubscriberProps>

Configure subscribers for this topic

new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/function1.handler",
subscriber2: "src/function2.handler"
},
});

cdk.id?​

Type : string

Allows you to override default id for this construct.

cdk.topic?​

Type : ITopic | TopicProps

Override the default settings this construct uses internally to create the topic.

Properties​

An instance of Topic has the following properties.

id​

Type : string

subscriberFunctions​

Type : Array<Function>

A list of the internally created function instances for the subscribers.

subscriptions​

Type : Array<Subscription>

Get a list of subscriptions for this topic

topicArn​

Type : string

The ARN of the internally created SNS Topic.

topicName​

Type : string

The name of the internally created SNS Topic.

cdk.topic​

Type : ITopic

The internally created CDK Topic instance.

Methods​

An instance of Topic has the following methods.

addSubscribers​

addSubscribers(scope, subscribers)

Parameters

Add subscribers to the topic.

const topic = new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/function1.handler",
subscriber2: "src/function2.handler"
},
});
topic.addSubscribers(stack, {
subscriber3: "src/function3.handler"
});

attachPermissions​

attachPermissions(permissions)

Parameters

Attaches the given list of permissions to all the subscriber functions. This allows the subscribers to access other AWS resources.

const topic = new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/function1.handler",
subscriber2: "src/function2.handler"
},
});
topic.attachPermissions(["s3"]);

attachPermissionsToSubscriber​

attachPermissionsToSubscriber(subscriberName, permissions)

Parameters

Attaches the list of permissions to a specific subscriber.

const topic = new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/function1.handler",
subscriber2: "src/function2.handler"
},
});

topic.attachPermissionsToSubscriber("subscriber1", ["s3"]);

bind​

bind(constructs)

Parameters

  • constructs Array<SSTConstruct>

Binds the given list of resources to all the subscriber functions.

const topic = new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/function1.handler",
subscriber2: "src/function2.handler"
},
});
topic.bind([STRIPE_KEY, bucket]);

bindToSubscriber​

bindToSubscriber(subscriberName, constructs)

Parameters

  • subscriberName string
  • constructs Array<SSTConstruct>

Binds the given list of resources to a specific subscriber.

const topic = new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/function1.handler",
subscriber2: "src/function2.handler"
},
});

topic.bindToSubscriber("subscriber1", [STRIPE_KEY, bucket]);

TopicQueueSubscriberProps​

Used to define a queue subscriber for a topic

new Topic(stack, "Topic", {
subscribers: {
subscriber: {
type: "queue",
queue: new Queue(stack, "Queue", {
consumer: "src/function.handler"
})
}
}
})

queue​

Type : Queue

The queue that'll be added as a subscriber to the topic.

type​

Type : "queue"

String literal to signify that the subscriber is a queue

cdk.subscription?​

Type : SqsSubscriptionProps

This allows you to override the default settings this construct uses internally to create the subscriber.

TopicFunctionSubscriberProps​

Used to define a function subscriber for a topic

new Topic(stack, "Topic", {
subscribers: {
subscriber: "src/function.handler"
}
})

function​

Type : string | Function | FunctionProps

Used to create the subscriber function for the topic

type?​

Type : "function"

String literal to signify that the subscriber is a function

cdk.subscription?​

Type : LambdaSubscriptionProps

This allows you to override the default settings this construct uses internally to create the subscriber.