About Amazon SNS & Pub/Sub Architecture
Tags: aws, serverless, javascript, cloud
Published: 2023-04-04 13:45:05

In this article will delve into one of the messaging techniques used in event-driven architectures, which is Pub/Sub.

### About Amazon SNS - Push Notification Service:

AWS SNS (Simple Notification Service) is a messaging and mobile push notification service provided by Amazon Web Services (AWS). It allows developers to send messages or notifications to a large number of recipients, such as end-users or other applications, via multiple communication protocols like SMS, email, mobile push notifications, and others. It's commonly used to build distributed, event-driven applications and microservices.

### About Pub/Sub:

Publish/Subscribe messaging, or pub/sub messaging, is a form of asynchronous service-to-service communication used in serverless and microservices architectures. In a pub/sub model, any message published to a topic is immediately received by all of the subscribers to the topic.

The intermediate system that functions as an event router is referred to as a "Topic". Any service that has subscribed to this Topic will receive messages whenever they are published by the designated publisher.

### Examples:

Let's see a simple example of using the Serverless Framework to implement a Pub/Sub architecture using AWS SNS and AWS Lambda. The publish function publishes a message to the test-topic SNS topic, and the process function subscribes to the topic and processes incoming messages.

- The SNS topic definition to your `serverless.yml` file:
```yaml
resources:
  MySNSTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: test-topic
```

- Our two Lambda functions, the one that will publish a message to the SNS topic (publisher), and the will consumer the message (subscriber)

```javascript
const AWS = require('aws-sdk');
const sns = new AWS.SNS();

module.exports.publisher = async (event) => {
  const params = {
    Message: event.body,
    TopicArn: process.env.SNS_TOPIC
  };
  const result = await sns.publish(params).promise();
  console.log('result =>', result);

  return {
    statusCode: 200,
    body: 'Message published successfully'
  }
}

module.exports.subscriber = async (event) => {
  const message = event.Records[0].Sns.Message;
  console.log(`Received message: ${message}`);

  return {
    statusCode: 200,
    body: 'Message processed successfully'
  }
}
```

- The publisher function will be a simple API, which we will trigger later on from postman. And the subscriber (If an arn: is specified, the framework will give permission to the topic to invoke the function and subscribe the function to the topic)

```yaml
publisher:
  handler: src/modules/PubSub/controller/lambda.publisher
  events:
    - http:
        method: post
        path: sns/pub
        cors: true
subscriber:
  handler: src/modules/PubSub/controller/lambda.subscriber
  events:
    - sns:
        arn: arn:aws:sns:${env:region}:${env:accountId}:test-topic
```

That's it now let's try to hit our API, will pass the following body:
```json
{
  "data": "test"
}
```
Now you can see our subscriber function being triggered and will print the following body message inside the cloudwatch

### Conclusion:
In event-driven architecture it's always good practice to spread your services, and make them decoupled, this will make your infrastructure much easier to be managed and scaled at the same time. 🙂

This was a short one, but I hope it will help someone out there to tackle a problem or have an "aha" moment.

This article is part of the "Messaging with Serverless" series that I have been writing for a while. If you are interested in reading about other serverless offerings from AWS, feel free to visit the links below.