What is AWS Simple Notification Service?
Simple Notification Service (SNS) is a highly available, managed pub/sub (publisher/subscriber) messaging service provided by AWS. There are many possible use cases for SNS, but I’m going to focus on one, based around a recent requirement I needed to fulfil. At a high-level, SNS supports the concept of a topic, to which messages are published. Each topic can then have zero or more subscribers configured which can include other AWS services such as AW SQS for example. Those subscribers will receive a notification when a new message is available.
I’m in the process of building out an initial prototype for a system which will support the collection and storage of auditing event data. Various source services will generate audit events when certain activities occur. The system I am building must support multiple consumers of the audit events. Each consumer may perform actions to store or index the audit data, as well as to potentially trigger other downstream services and workflows.
Using SNS as the messaging platform provides a simple and relatively cheap way to design such a system.
The preceding diagram shows a simplified version of the flow I needed to build, with scope for additional subscribers in the future.
While I won’t go into detail, I’ll briefly describe the setup in AWS to support the sample I will show. To follow these steps you’ll need an AWS account to work with.
Creating a Topic
The first thing you’ll need to do is create an SNS topic. You can do this via the AWS Console by choosing “Create topic”.
Provide a suitable name for the topic.
Create a Subscriber
Next, we’ll add a subscriber to the topic. In my case, I’m adding an existing SQS queue.
For SNS to be able to send to SQS, you’ll need to enable permissions on the queue, granting the SNS topic ARN with SendMessage permissions.
For full details of the process, I suggest you refer to the AWS documentation.
Publishing to SNS from ASP.NET Core
With SNS set up and ready to receive messages, we’ll use a simple ASP.NET Core Razor Pages project for this sample. For demonstration purposes, I’ll trigger sending a message to SNS every time the Index page is visited.
We’ll need to add two packages to our project. The first is called “AWSSDK.Extensions.NETCore.Setup”. This package provides extensions for registering AWS services with the Microsoft dependency injection container.
The second package is “AWSSDK.SimpleNotificationService”. This provides the client library to support making calls to SNS. You can add these packages via your preferred method, I chose to use the dotnet add package CLI command.
Once completed, my project file looks like this…
Next, we need to ensure that the SDK can pick up credentials to access AWS services. Register the AWS options using the following extension method.
This expects to be able to pick up valid credentials from one of the default locations. You can read more about configuring the SDK and credentials in the AWS SDK for .NET documentation.
With the SDK configured, we also need to register the SNS client services. We can do this by using the AddAWSService<T> extension method, passing in the AWS service we wish to register, in this case, IAmazonSimpleNotificationService.
This concludes the set up work to register all of the required services and configuration. We are now ready to publish a message to SNS.
Publishing a Message to SNS
Publishing to SNS is actually quite simple. First, we must define a request to the SNS service which will send our message.
There are two required properties to support our scenario. The first is the message itself, which is just a string. In the preceding example I’m constructing a basic message but in our real implementation, we’re sending a JSON serialise message. The second property is the ARN for the SNS topic to which we want to send. In this example, I’ve hard-coded it into the request but a better design in a production system would be to load this from configuration.
Within the same account and region, the first part of the ARN will remain the same for all topics. Therefore it’s possible build up an ARN dynamically if you need to, as long as you know the name of the topic you need to send to.
With the request defined, we can now publish it to SNS using the PublishAsync method.
In this example, I am passing the request object as an argument. PublishAsync also supports overloads accepting the message and topic ARN directly if you prefer. It also supports cancellation if necessary by providing a cancellation token.
The PublishAsync method will return a PublishResponse, which includes a status code as well as the message ID for the published message. It’s a good idea to check that the publish response is successful and handle any exceptions that PublishAsync may throw.
You can wrap the publish call in a try/catch block and specifically catch any exceptions you wish to deal with. Various exceptions are defined for things such as authorization failures or trying to send to a topic which cannot be found. You can refer to the AWS SNS API documentation for details of all possible exceptions.
That’s all we need to do in this simple example. The complete sample code can be found on my GitHub repo.
If I now run the application it loads the home page, which will publish an SNS message. Because I subscribed an SQS queue to the topic, if I check the current messages on that queue, I can see one from the homepage visit.
The message body, in this case, wraps the original SNS message. If you prefer you can configure your subscription to forward a raw message directly from SNS.
This concludes this post. I hope you have seen that it’s very straight-forward to publish to SNS from a .NET Core or ASP.NET Core application using the provided SDK. SNS provides a pretty quick solution for building out distributed systems where a pub/sub model is needed.
Thank you for reading!
If you enjoyed this post and found it useful, why not: