Topic
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 "sst/constructs";
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(stack, {
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(stack, "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(stack, "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(stack, "MySnsTopic", topicArn),
},
});
Constructor
new Topic(scope, id, props)
Parameters
- scope Construct
- id string
- props TopicProps
TopicProps
defaults?
Type :
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, Queue | string | Function | TopicQueueSubscriberProps | TopicFunctionSubscriberProps>
Configure subscribers for this topic
new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/function1.handler",
subscriber2: "src/function2.handler"
},
});
cdk?
Type :
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
Type :
cdk.topic
Type : ITopic
The internally created CDK
Topic
instance.
Methods
An instance of Topic
has the following methods.
addSubscribers
addSubscribers(scope, subscribers)
Parameters
- scope Construct
- subscribers
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
- permissions Permissions
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
- subscriberName string
- permissions Permissions
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<BindingResource>
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<BindingResource>
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?
Type :
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?
Type :
cdk.subscription?
Type : LambdaSubscriptionProps
This allows you to override the default settings this construct uses internally to create the subscriber.