Skip to main content

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.

Constructor

new Topic(scope, id, props)

Parameters

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", {
subscribers: {
subscriber1: "src/subscriber1.main",
subscriber2: "src/subscriber2.main",
},
cdk: {
topic: {
fifo: true,
},
},
});

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),
},
});

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 | TopicQueueSubscriberProps | Queue | TopicFunctionSubscriberProps>

Configure subscribers for this topic

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

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.

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 given subscriber by index

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

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

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.