Amazon SNS For the .NET Developer: Getting Started Quick and Easy

Learn how to get started with Amazon SNS and use it from a .NET application. We will learn about Topics, sending messages to topics, and using Subscriptions to receive messages. We will also learn about Filters, how to use them, and error handling with SNS.

Rahul Pulikkot Nath
Rahul Pulikkot Nath

Table of Contents

This article is sponsored by AWS and is part of my AWS Series.

Amazon Simple Notification Service or SNS, is a publish-subscribe service, managed by AWS.

It enables asynchronous communication between the publishers and subscribers using messages.

SNS supports application-to-application and application-to-person communication. Amazon SNS is useful when building distributed systems, microservices, event-driven serverless applications, etc.

In this article, we will learn how to get started with Amazon SNS and use it from a .NET application. We will learn about Topics, sending messages to topics, and using Subscriptions to receive messages. We will also learn about Filters, how to use them, and error handling with SNS.

Create SNS

To get started, let’s first create an SNS. The straightforward way to create an Amazon SNS is from the AWS Console.

Amazon SNS supports two types of Topics

  • Standard → Provides best-effort message ordering and guarantees at-least once message delivery. These are better suited for use cases that require higher message publish and delivery throughput rates. Supports SQS, Lambda, HTTP, SMS, email, and mobile application endpoints as the subscription protocols.
  • FIFO (first-in, first-out) → Guarantees message ordering and exactly-once message delivery. Supports only SQS subscription protocol.

For this article, we will create a Standard SNS Topic, by specifying the name and leaving all other options to default.

Amazon SNS create new Standard topic from the AWS Console

SNS & .NET

We will use the ASP NET Core default Web API template as our sample application. The application has a GET method to return WeatherForecast data by default.

The source code used in this blog post is available here.

The AWSSDK.SimpleNotificationService NuGet package provides the AmazonSimpleNotificationServiceClient that’ useful to interact with Amazon SNS.

You can connect by passing the credentials explicitly or setting up the credentials for your environment.

Publisher - Send Message

In our API example, let’s say we add a new POST endpoint to add new WeatherForecast data to our application. And let’s assume when new weather data is added, we want to email and also we want to generate some new reports.

The application or the source that sends messages to the SNS is the Publisher.

It’s a good practice to decouple applications actions into their own isolated process, so that we can track and manage them independently. For example, if an email fails, we can retry it separately, and it doesn’t have to affect regenerating the report or saving new weather data itself.

Publishing a message to a publish-subscribe service allows us to decouple application logic. When adding new weather data, we can publish a message to the Amazon SNS Topic and we can have multiple subscribers that can do the associated actions of sending an email or regenerating the report.

Use the PublishAsync method on the AmazonSimpleNotificationServiceClient to send the PublishRequest message which contains the Subject, Message the ARN of the SNS Topic.

[HttpPost]
public async Task Post(WeatherForecast data)
{
    var client = new AmazonSimpleNotificationServiceClient();
    var request = new PublishRequest()
    {
        Subject = "WeatherForecastAddedEvent",
        Message = JsonSerializer.Serialize(data),
        TopicArn = "arn:aws:sns:us-east-1:189107071895:weather-forecast",
    };
    
    var response = await client.PublishAsync(request);
}

Subscriber → Receive Message

The published messages are of no use having no subscribers.

To receive messages send to a topic by the publisher, you must subscribe to the topic

Messages published are sent immediately to all Subscribers of the Topic

There are different mechanisms to add subscribers to the Topic, and the easiest is to from the console. Let’s look at two different subscribers for our use of sending email and reprocessing a report.

We can add a new subscription under the Topic in the AWS console.

Email Subscription

To email, any time we receive a message in the Topic, create a new Subscriber with the Email Protocol. Enter the email address of the recipient in the Endpoint column.

Use Email Protocol for the subscriber and specify the email to which the messages must be sent. Everytime a message comes in the SNS Topic the subscriber will receive an email.

Once created, a confirmation email is sent with a link. Only after confirming the subscription using the link will messages appear in the email inbox.

The message body or structure cannot be changed for this native email protocol. It sends the raw message as text to the email specified. Depending on the chose protocol (Email or Email-JSON) the contents are different in format. Email-JSON sends the notification in JSON format, whereas Email sends it as plain text.

To send rich formatted business emails, you can use SNS along with Amazon Simple Email Service(SES)

Lambda Subscription

You can also trigger AWS Lambda Functions any time you receive a message in the Topic.

AWS Lambda For The .NET Developer
Learn to build Serverless Applications on AWS

Below is the default AWS Lambda template function using the Simple SNS Function Blueprint.

public async Task FunctionHandler(
    SNSEvent evnt, ILambdaContext context)
{
    foreach(var record in evnt.Records)
    {
        await ProcessRecordAsync(record, context);
    }
}

private async Task ProcessRecordAsync(
    SNSEvent.SNSRecord record, ILambdaContext context)
{
    context.Logger.LogInformation($"Processed record {record.Sns.Message}");

    // TODO: Do interesting work based on the new message
    await Task.CompletedTask;
}

Once you publish the Lambda function to AWS, you can set up a new SNS Subscription either from the SNS Topic list or from the AWS Lambda Triggers list.

Grant, the IAM Role of Lambda Function has access to the SNS before adding in the subscription. This is required so that the Lambda function can access the SNS Topic.

AWS Lambda permissions to access Amazon SNS - In this case it has full access to the specific SNS Topic.

Under the Lambda → Triggers, you can add a new Trigger and set up the integration with Amazon SNS.

Setting up a SNS Trigger for Amazon Lambda. Every time a message is dropped to the Amazon SNS Topic the .NET lambda function will be triggered

Once the Trigger is created, any time a new message is sent to the Amazon SNS, it will trigger the Lambda function as well.

SNS Message Filtering

By default, the SNS Topic subscriber receives every message published to the topic.

However, SNS provides ways to apply filter policies when creating subscriptions.

Filter Policy is a JSON document that specifies attributes used to filter the messages received by a subscriber.

Filter Policies are key-value pairs of attributes, names, and values. The Subscriber receives only the messages for which the specific properties match the values in the policy.

Let’s say we want to filter out messages based on the month of the Weather Forecast.

Using the below code, let’s add a new custom Message Attribute before sending the message to SNS.

request.MessageAttributes.Add(
    "Month",
    new MessageAttributeValue()
    {
        DataType = "String",
        StringValue = data.Date.ToString("MMMM")
    });

For the Subscriber, where we want to apply the filter policy, we can edit it in the AWS Console → Edit Subscription.

{
  "Month": [
    "February"
  ]
}

Specifying the below policy filters out only the messages which have the Month property set to February. It will filter anything else out.

Subscription Filter policy to filter out messages from Amazon SNS Topic only for the month of Februrary.

Filter Policies JSON structure supports different filtering capabilities

  • Exact Matching → Attribute matches one or more values ”Month” : [”February”]
  • Prefix Matching → Attribute includes the keyword prefix and it matches the specified prefix. Below matches March and May”Month” : [{”prefix”: “Ma”}]
  • Anything-but Matching → This does an exclusion match. Below matches all months other than February and March. "Month": [{"anything-but": ["February", “March”]}]

Retries & Dead-letter Queues

When Amazon SNS cannot deliver a message to the Subscriber, it will retry to deliver the message again. The delivery policy is defined based on the delivery protocol (Lambda, Email, SQS etc).

You can see the Delivery protocols and the associated policies here. You can override the policy at the Topic Level by editing the Topic.

Delivery Retry Policy for the Amazon SNS Topic

Once the number of retries is exhausted for a delivery protocol, the message is discarded or sent to a dead-letter-queue (DLQ) attached to the subscription.

Dead letter Queue (DLQ) attached to a Amazon SNS Subscription.

Dead Letter Queue's (DLQ) are attached to a SNS Subscription.

Messages can be tracked and reprocessed from the DLQ as required, based on your application needs and if the Subscriber is back online to process messages.

I hope this gives you an excellent introduction to Amazon SNS and helps you get started from a .NET Application.

AWSServerlessDotnet-Core