Topics / Subscribers (Pub / Sub)
Less makes it easy to set up topics and subscribers (pub/sub) giving you powerful features by default:
- Publish messages with at-least-once delivery guarantees.
- Failed messages are retained by Less in order to be processed again later.
- Failed messages to not block the processing of subsequent messages.
- Easily implement the Fanout arquitectural pattern.
- Publish and subscribe to topics from different Less applications securely.
- Easily build event-driven microservices.
- Generated Topics REST API allowing you to publish messages from anywhere.
- Easily integrate with your existing systems.
- Easily scale and distribute your workloads.
Create Topics
In order to create topics (publishers) and subscribers you need to create a topics
folder in less
. Each folder inside of topics
is your topic.
mkdir -p less/topics
Let's create a user_created
topic:
mkdir less/topics/user_created
Create Topic Subscribers
A topic can have several subscribers. Just add them to your topic's folder.
Let's create some example subscribers to the user_created
event:
mkdir less/topics/user_created/send_welcome_email
mkdir less/topics/user_created/send_to_analytics
- Node.js
- Python
touch less/topics/user_created/send_welcome_email/index.js
exports.process = async (user) => {
console.log(`Sending a welcome email to ${user.email}`);
};
exports.process = async (user) => {
console.log(`Sending user "${user.name}" to analytics`);
};
touch less/topics/user_created/send_welcome_email/__init__.py
def process(user):
print(f"Sending a welcome email to {user['email']}")
def process(user):
print(f"Sending user \"{user['name']}\" to analytics")
Send Messages to Topics
Less offers 2 ways to send messages to topics:
- Using the
topics
module in the Less SDK. - Using the Less Topics REST API.
Send Messages Using the SDK
Use the Less topics
module to send messages to all of a topic's subscribers.
- Node.js
- Python
const { topics } = require('@chuva.io/less');
await topics.user_created.publish(message);
Import topics
from less
to send messages to all subscribers.
from less import topics
topics.user_created.publish(message)
Let's create a POST /users
route that will send the user payload to the user_created
topic.
- Node.js
- Python
touch less/apis/demo/users/post.js
const { topics } = require('@chuva.io/less');
exports.process = async (request, response) => {
// Get the user payload from the body.
const user = JSON.parse(request.body);
// Pretend to create a new user.
const new_user = { id: 'my-fake-id', ...user };
// Publish the new user to the `user_created` topic.
await topics.user_created.publish(new_user);
};
touch less/apis/demo/users/post.py
import json
def process(request, response):
body = json.loads(request['body'])
user = body['user']
user['id'] = 'my-fake-id'
topics.user_created.publish(user)
Read the Less REST API documentation to learn more.
You can now deploy and call your POST /users
route and confirm that your subscribers are receiving the messages:
- Deploy your changes.
- npx
- npm
- yarn
npx @chuva.io/less-cli deploy my-less-project
less-cli deploy my-less-project
less-cli deploy my-less-project
- Execute your
POST /users
request.
curl -X POST -d '{"name": "Mayra Andrade", "email": "mayra.andrade@chuva.io"}' [BASE_URL]/users
- Check your subscriber logs and confirm your messages were received.
- npx
- npm
- yarn
npx @chuva.io/less-cli log --project my-less-project --path topics/user_created/send_welcome_email
npx @chuva.io/less-cli log --project my-less-project --path topics/user_created/send_to_analytics
npm i -g @chuva.io/less-cli
less-cli log --project my-less-project --path topics/user_created/send_welcome_email
less-cli log --project my-less-project --path topics/user_created/send_to_analytics
yarn global add @chuva.io/less-cli
less-cli log --project my-less-project --path topics/user_created/send_welcome_email
less-cli log --project my-less-project --path topics/user_created/send_to_analytics
Read the Less logs documentation to learn more.
Send Messages Using the REST API
When using the Topics feature, Less automatically creates a Topics REST API for you. You can use the API to publish messages to your Topics from anywhere, making it easy to integrate Less with your existing systems.
- Deploy your topics.
- npx
- npm
- yarn
npx @chuva.io/less-cli deploy my-less-project
less-cli deploy my-less-project
less-cli deploy my-less-project
- Retrieve your Topics API URL from your deployment output:
[less-cli] Deployment complete ✅
[less-cli] Resources
[less-cli] - API URLs
[less-cli] - Topics: https://[PROJECT_NAME]-topics.api.eu-0.a83b464c9.less.chuva.cv
[less-cli] 🇨🇻
- Send a message to your
user_created
topic using thePOST /topics/{topic_name}
route.
curl -X POST -d '{"name": "Mayra Andrade", "email": "mayra.andrade@chuva.io"}' [TOPICS_BASE_URL]/topics/user_created
- Check your subscriber logs and confirm your messages were received.
- npx
- npm
- yarn
npx @chuva.io/less-cli log --project my-less-project --path topics/user_created/send_welcome_email
npx @chuva.io/less-cli log --project my-less-project --path topics/user_created/send_to_analytics
npm i -g @chuva.io/less-cli
less-cli log --project my-less-project --path topics/user_created/send_welcome_email
less-cli log --project my-less-project --path topics/user_created/send_to_analytics
yarn global add @chuva.io/less-cli
less-cli log --project my-less-project --path topics/user_created/send_welcome_email
less-cli log --project my-less-project --path topics/user_created/send_to_analytics
POST /topics/{topic_id}
Handling Failing Messages
Less automatically retains failed messages and tries to process them again later.
In order to see this in action we can force a crash in one of our subscribers:
- Node.js
- Python
touch less/topics/user_created/send_welcome_email/index.js
exports.process = async (user) => {
throw new Error('This subscriber will fail to process messages.');
console.log(`Sending a welcome email to ${user.email}`);
};
touch less/topics/user_created/send_welcome_email/__init__.py
def process(user):
raise SyntaxError('This subscriber will fail to process messages.')
print(f"Sending a welcome email to {user['email']}")
Deploy the change and publish another message to your topic. You will notice that while the user_create/send_welcome_email
subscriber is failing, the user_create/send_to_analytics
subscriber is working just fine.
Once we fix the crash and deploy we will notice that the previously failing message will be processed successfully.
Cross-Application Topics
Less also makes it easy to subscribe to topics from different Less applications. This makes it easier than ever to build distributed, fault-tolerant, event-driven microservices.
Subscribe to External Topics
- Create an
external_topics
folder inside ofless
to set up your external app connections.
mkdir -p less/external_topics
- Add the projects you want to connect to to the
external_topics
folder.
mkdir less/external_topics/my_less_project
- Add the topic want to subscribe to to the respective project folder.
mkdir less/external_topics/my_less_project/user_created
- Create your subscriber
- Node.js
touch less/external_topics/my_less_project/user_created/index.js
exports.process = async (user) => {
console.log('Telling all your friends that you have joined...');
};
- Configure your project connection.
Add the folder name to the
less.config
file as an environment variable. The value of this variable should match the name of the application you want to connect to.
env_vars:
- MY_LESS_PROJECT
Export the name of the application (deployment) you want to connect to. This allows you to point your application to different deployments (development, stage, production, etc.).
export MY_LESS_PROJECT=my_less_project
Read the Less environment variables documentation to learn more.
less/topics
folder, we are not creating topics here. In this case we are simply connecting to a topic from the specified application.You can now deploy your new application. Publish messages to the first application and verify they are received in your new external subscriber.