Problem
You need to develop with using Amazon SNS, but you don´t have enough Budget. Or you want to impress your Boss by saving money.
Solution
Enter Localstack.
They provide mocks of Amazon Services like the Simple Notification Service (SNS).
Requirement
Installed awscli (pip install awscli)
Installed awslocal (https://github.com/localstack/awscli-local) (Optional, Recommended)
To use SNS with LocalStack you can start it via your command line or via docker-compose.
I will show you both options.
CLI (Commandline)
To start SNS via LocalStack, execute the following command (based on your OS):
Linux
SERVICES=sns localstack start --docker
Mac OS
SERVICES=sns TMPDIR=/private$TMPDIR localstack start --docker
Mac OS requires the additional pointer to the TMPDIR.
Docker-Compose
version: '2.1'
services:
localstack:
container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
image: localstack/localstack
network_mode: bridge
ports:
- "4566:4566"
environment:
- SERVICES=sns
- DEBUG=${DEBUG- }
- DOCKER_HOST=unix:///var/run/docker.sock
- HOST_TMP_FOLDER=${TMPDIR}
volumes:
- "${TMPDIR:-/tmp/localstack}:/tmp/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
This docker-compose.yaml from the LocalStack GitHub Repository
Run docker-compose up
and you will be good to go.
Both
Either way you will have a LocalStack running locally that supports Amazon SNS.
If it´s the first time (or your cleaned up Docker) it might take a while to get the containers downloaded and running. Then you can get a coffee ;).
On following starts it should start almost instantly.
If you installed awslocal, you can verify that sns is up and running be executing awslocal sns list-topics
. Without awslocal you need to execute aws --endpoint-url=http://localhost:4566 sns list-topics
.
This is basically how to set it up.
Usage
To use Amazon SNS you need:
- a topic
- a subscription
- a message send
Topic
A topic is like a channel in slack or irc. It´s where message will go. It is used for the routing, similar to a url (especially REST URLs).
That can be alphanumeric and needs to be unique (on your account/your installation).
To create a topic test1
, you execute awslocal sns create-topic --name test1
. (look a bit up if you don´t use awslocal).
To list all available topics run
awslocal sns list-topics
Subscription
To receive messages you need to declare that you want to receive them and the target where you want to receive them. Think giving a woman your phone number.
To list all existing subscription topics:
awslocal sns list-subscriptions
Creating a subscription is a little bit more work. Usually you would do it in source code. But if you want to manually create a http subscription you run this:
awslocal sns subscribe --topic-arn arn:aws:sns:us-east-1:000000000000:test1 --protocol http --notification-endpoint http://localhost:3000/incoming
Replace arn:aws:sns:us-east-1:000000000000:test1
with the TopicArn that you received when you created the topic or when you list the available topics.
Note: Subscribing via the aws(local) tool will confirm the subscription.
Subscribe via source code requires an extra call to confirm.
Note: On Mac OS you need to use docker.for.mac.localhost
instead of localhost when you are inside docker and need to access a process that runs in another container or directly on the host
Message
Last but not least you actually need to send a message which triggers the call.
You can do this by running this command (sending json data):
awslocal sns publish --topic-arn arn:aws:sns:us-east-1:000000000000:test1 --message-structure json --message '{"default":{"greeting": "Hello World"}}'
Replace the arn arn:aws:sns:us-east-1:000000000000:test1
with the arn your topic uses.
The json formatted as string ‘{“default”:{“greeting”: “Hello World”}}’ is what we want to send. To send json the top level default is required. Under it your can send your data.
Note: If you want to send a JSON {“orderId”: 123456, “restaurantId”: “abc”} your call looks like this:
awslocal sns publish --topic-arn arn:aws:sns:us-east-1:000000000000:test1 --message-structure json --message '{"default": {"orderId": 123456, "restaurantId": "abc"} }'
Removing a subscription
While you are experimenting to understand how everything works you probably want to remove a subscription.
To do that you run:
awslocal sns unsubscribe --subscription-arn arn:aws:sns:us-east-1:000000000000:test1:3508cf40-5ab9-4317-bded-ff6a8d42e0b6
Replace arn:aws:sns:us-east-1:000000000000:test1:3508cf40-5ab9-4317-bded-ff6a8d42e0b6
with the arn of your subscription
Remove a topic
Last but not least you might want to remove a topic. To do that call:
awslocal sns delete-topic --topic-arn arn:aws:sns:us-east-1:000000000000:test1
Replace arn:aws:sns:us-east-1:000000000000:test1
with the arn of your topic.
And that´s it.
Now you know how to set up local Amazon SNS and how to use it on the command line.
Stay tuned for the article how to access it with NodeJS.
Let me know when it helped you.
Best,
Frank
Sources:
https://github.com/localstack/awscli-local
https://docs.aws.amazon.com/cli/latest/userguide/cli-services-sns.html