[Infographic] AWS SNS from a serverless perspective
The Simple Notification Service, or SNS for short, is one of the central services to build serverless architectures in the AWS cloud. SNS itself is a serverless messaging service that can distribute massive numbers of messages to different recipients. These include mobile end-user devices, like smartphones and tablets, but also other services inside the AWS ecosystem.
SNS’ ability to target AWS services makes it the perfect companion for AWS Lambda. If you need custom logic, go for Lambda; if you need to fan out messages to multiple other services in parallel, SNS is the place to be.
But you can also use it for SMS or email delivery; it’s a versatile service with many possible use-cases in a modern serverless system.
See the original article for copyable code examples: https://dashbird.io/blog/aws-sns/
SNS is a serverless service, which means it comes with pay-as-you-go billing. You pay about 50 cents per 1 million messages. If your messages are bigger than 64 KB, you have to pay for each additional 64 KB chunk as if it was a whole message.
AWS also offers the first 1 million requests each month for free; this includes 100000 deliveries via HTTP subscription.
SNS vs. SQS
SNS’ parallel delivery is different from SQS, the serverless queuing service of AWS. If you need to buffer events to remove pressure from a downstream service, then SQS is a better solution.
Another difference is SQS is pull-based, so you need a service actively grabbing an event from a queue, and AWS SNS is push-based so that it will call a service, like Lambda, that waits passively for an event.
SNS vs. EventBridge
EventBridge has similar use-cases as SNS but operates on a higher level. EventBridge can archive messages and target more services than SNS. SNS’ only targets are email addresses, phone numbers, HTTP endpoints, Lambda functions, and SQS queues. This means if you want to give your data to another AWS service, you need to put some glue logic in-between. At least a Lambda function, and it will cost extra money.
But SNS allows configuring a topic as FIFO, which guarantees precisely one message delivery. This lowers the throughput from about 9000 msgs/sec to about 3000 msgs/sec but can reduce the complexity of your Lambda code.
Don’t call Lambda from another Lambda
One rule when building serverless systems is “Don’t call a Lambda directly from another Lambda.” This rule comes from the fact that events from direct calls can get lost when one of the functions crashes, or it could lead to one function waiting until the other function finishes, which means double the costs.
This direct call rule means you always should put another service between your Lambda function calls. Sometimes these services follow from your use-cases, but when they don’t, and you’re about to make a direct call, you can grab SNS, EventBridge, or SQS to get around this issue.
Using SNS from Lambda
There are two ways SNS interacts with AWS Lambda: First, Lambda can send an event to an SNS topic, and second, a Lambda can subscribe to an SNS topic and receive events from it.
Sending Events from Lambda to an SNS Topic
To send a message to an SNS topic from your Lambda function, you need the SNS client from the AWS SDK and the ARN of your SNS topic.
Let’s look at an example Lambda that handles API Gateway events:
The Lambda uses the AWS SDK v3, which is better modularized than the v2, which means more space for your custom code inside a Lambda.
It’s a good practice to store the SNS topic ARN inside an environment variable, so you can change it without changing the code. Also, you should initialize the SNS client outside of the function handler, so it only happens on a cold-start.
You need to call the send method with a PublishCommand object to publish messages. The object requires a Message string, which we get from our API Gateway event body, and the TargetArn we got from an environment variable.
Receiving SNS Events with Lambda
To receive an SNS event with a Lambda, you need to subscribe your Lambda to an SNS topic. This way, the event that invokes the Lambda will be an SNS message.
Let’s look at how to set things up with the CDK:
The first crucial part here is that you need to wrap the Lambda function into a subscription so that the CDK can link it up with an SNS topic.
The second part is that the event your Lambda function receives has its data inside a Records array, so you need to iterate it to get every record.
Piping API Gateway Events to SNS
Using AWS Lambda to glue things together is pretty straightforward but adds complexity and latency and costs extra money. That’s why you should do simple integrations directly between services like API Gateway and SNS.
Let’s look at another CDK example:
The example uses a third-party library that takes care of the event transformations. Usually, you would use the AwsServiceIntegration construct, which requires you to write VTL code that transforms the API Gateway event into something SNS understands. The library comes with some transformations out-of-the-box.
If you send JSON via a POST request to the /emails resource of this REST API, API Gateway will directly pipe that data to the SNS topic; no Lambda needed!
Dashbird now supports SNS
Now that you learned that AWS SNS is a crucial part of many serverless systems, you should be happy to hear that with its latest update, Dashbird gives you insights into your SNS topics too!
With its ability to run custom code, Lambda was low-hanging fruit for debugging; you could push all you wanted to know to a monitoring service. But all the other services on AWS are a bit trickier.
Usually, you would learn about the issues inside other services when Lambda was calling them. But Lambda costs money, and some services, like API Gateway or EventBridge, are perfectly able to transform and distribute events directly to the services where they’re needed. No Lambda needed, and that’s how it should be! Only use Lambda if it simplifies something or if the direct integrations lack features.
With Dashbird’s new AWS SNS integration, you can now discover what is happening inside your architecture without the need to sprinkle Lambda functions all around the integration points. This saves you money, latency, and complexity!