If you’re building modern applications, you’ve probably dabbled in event-driven architectures (EDA). These are architectural patterns in distributed systems where components are purposefully designed to be loosely coupled and to react to specific events or triggers. When combined with serverless architectures, they enable new heights of scalability, flexibility, and responsiveness.
We built Momento Topics to be a serverless event bus—a critical structure that connects applications to each other with low latency, low cost, and low effort. With Topics, you can create an interactive messaging app with millions of subscribers in an afternoon. You can even connect your mobile applications directly to Momento—avoiding WebSocket headaches and web server fleets in general. Momento can even store the messages long term in Momento Cache.
Upon launching Momento Topics, we quickly realized a contradiction in our serverless vision: consuming a topic on the backend required customers to setup a server, which does nothing except listen to your topic of choice.
Enter webhooks! Momento webhooks allow you to simply register an HTTP endpoint that can be invoked every time a message is published to a topic. Now, you can easily trigger a Lambda function to react to messages.
Why webhooks for Momento Topics are so powerful
Imagine you built a chat application on Momento Topics—and it suddenly grew popular. We already established that Momento can handle millions of concurrent users—but as you gain users, you realize two problems: first, your user base is global and would love to talk to each other unencumbered by language. Second, content moderation is crucial to maintain a safe and inclusive environment. How can EDA patterns help us add these capabilities into your application with Momento Topics and webhooks?
When you have two users chatting with each other in a chatroom named friends, you’d typically have the users publish and subscribe to the same topic. However, with a few simple changes, you can inject moderation and translation. We start by decoupling the publish and subscribe parts of the chat room. Each user publishes to friends-publish and subscribes to friends-subscribe-english. But how do you plumb these two topics together?
Start by creating a simple Lambda function that echoes whatever message it receives onto friends-subscribe-english. Then, you simply attach a webhook to the friends-publish topic to invoke this function. Now, whenever a message is published on friends-publish, it automatically gets echoed to friends-subscribe-english. What if you suddenly get a user that wants to read the conversation in Spanish?
Enabling Spanish translation is a simple three-step process:
- Modify the aforementioned Lambda to translate any message it gets into Spanish using Amazon Translate.
- Publish the translated Spanish message to friends-subscribe-spanish
- Subscribe the user interested in reading the conversation in Spanish to the friends-subscribe-spanish topic.
The power of EDA starts to emerge at this point. Now, if you wanted to add a Japanese channel, you can simply start writing to the friends-subscribe-japanese topic. You may also realize that users are publishing the messages in Japanese or Spanish, so you can simply go through Amazon Translate to detect and translate anything not in English to English before publishing to friends-subscribe-english topic.
As your user base grows, you may also realize the need for content moderation. After all, people say all kinds of things on the Internet. Remember EDA? You can now enable this Lambda function to do content moderation upfront. But there are some nuances you ought to consider.
First, if you intend to limit visibility of the unmoderated topics, you need to ensure that the credentials generated for a user does not have the permission to subscribe to the friends-publish topic, while maintaining the permissions to publish to it. This can be done using fine-grained access control and disposable tokens in Momento. You can give users subscribe permission to the topics of your choice as well. Since Momento’s access control is flexible, you can even make translation support in your app a paid feature and only offer subscribe permissions to the languages that a user has paid to subscribe to. The intent here isn’t to imply that one should or should not charge for translation, but simply to illustrate the flexibility that EDA and Momento offer to adapt to your business model.
Did I mention that EDA is really powerful? A general cross-language moderation system is a really difficult problem. However, with this architecture you can have language-specific moderation and plumb each translated topic to its custom/language-specific moderation function. Best of all, you can keep chaining Lambda functions to each other to compose complex workflows with simple building blocks that you can reason about independently and adapt as your workflow evolves.
See Momento Topics and webhooks in action
Matt and Rishti at Momento already built a hosted Vercel application that illustrates this pattern and they have open-sourced the software for it (with CDK for your Lambda function and everything). The most surprising part to us was, despite having multiple hops in the process (publishing to a topic, invoking a Lambda function, calling Amazon Translate, and running the profanity filter), the chat experience is ridiculously fast. You get instant translation regardless of the language you are subscribed to and publishing with. The demo is for a browser app, hosted by Vercel, but you don’t have to limit yourself to browsers. Momento Topics now supports native iOS, Elixir, Unity, and more—and you can connect the clients to each other on the same set of topics to get the scalable, moderated, and translated chats across all of your platforms. Isn’t EDA wonderful?