RabbitMQ Topic Exchange Explained
Topic Exchanges in RabbitMQ route messages based on wildcard matches on the message routing key specified on the queue binding. With Topic Exchanges, consumers can subscribe to topics they are interested in, like subscribing to a feed or individual tags.
Table of Contents
An Exchange in RabbitMQ is a routing mechanism to send messages to queues.
RabbitMQ supports four Exchange Types: Topic Exchange, Direct Exchange, Fanout Exchange, Headers Exchange.
In this blog post, let's understand
- RabbitMQ Topic Exchange
- Routing messages in Topic Exchange
- RabbitMQ Topic Exchange From a .NET application.
I use Amazon MQ, a managed message broker service that supports ActiveMQ and RabbitMQ engine types, to host my RabbitMQ instance. However, you can use one of the various options that RabbitMQ provides to host your instance,
This article is sponsored by AWS and is part of my RabbitMQ Series.
What is a RabbitMQ Topic Exchange?
Topic Exchanges in RabbitMQ route messages based on wildcard matches on the message routing key specified on the queue binding.
With Topic Exchanges, consumers can subscribe to topics they are interested in, like subscribing to a feed or individual tags.
Messages matching the criteria are sent to the appropriate queue.
If no bindings use wildcards, a Topic Exchange behaves like a Direct Exchange and you are better off using that.
Message Routing in RabbitMQ Topic Exchange
Topic exchanges route messages to one or many queues based on matching between a message routing key and the pattern on the Exchange binding key.
You can use wildcards when specifying a Binding key, and all messages with a routing key matching the wildcard are considered matches.
The message routing key in a Topic Exchange is usually a list of words delimited by dots. This makes it easy to use wildcards to filter messages. e.g. color.orange, aus.nsw.syd, stock.usd.nyse etc
Binding Wildcards in Topic Exchange
When specifying the binding key, you can use two wildcard formats.
- # (Hash) → Matches zero or more words
- * (Star) → Match one word
For example let's say we have messages sent to the queue for a Weather API application. The routing key takes the format of country.state.city codes (aus.nsw.syd).
If a consumer is interested in all messages for the NSW state in Australia, it can specify the binding with key aus.nsw.*. This sends all messages with 'aus.nsw' to that.
Similarly, if a consumer is interested in all messages on Australia, it can specify 'aus.#', which matches any message that starts with the aus. prefix.
RabbitMQ Topic Exchange From .NET
We will use a NuGet package, RabbitMQ.Client, to connect and send/receive messages from RabbitMQ.
If you are new to building RabbitMQ from .NET applications, check out the Getting Started article below.
Create and Send Messages to RabbitMQ Topic Exchange From .NET
Exchanges are created using the Channel.
The ExchangeDeclare
the method takes in an exchange name and its type. Below is an example of creating a RabbitMQ Topic Exchange in .NET.
var factory = new ConnectionFactory()
{
Uri = new Uri("YOUR RABBIT INSTANCE URI"),
Port = 5671,
UserName = "<USERNAME FROM CONFIGURATION FILE>",
Password = "<PASSWORD FROM CONFIGURATION FILE>"
};
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
var exchangeName = "weather_topic";
channel.ExchangeDeclare(exchangeName, ExchangeType.Topic);
When sending a message, the sender specifies the Exchange and the routing key.
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchangeName, routingKey, null, body);
Set up Binding on RabbitMQ Topic Exchange From .NET
Messages are routed to Queues from Exchanges using the Binding information.
To create a Queue, use the QueueDeclare
method. It will create a new Queue only if one doesn't exist with the same name.
var factory = new ConnectionFactory()
{
Uri = new Uri("YOUR RABBIT INSTANCE URI"),
Port = 5671,
UserName = "<USERNAME FROM CONFIGURATION FILE>",
Password = "<PASSWORD FROM CONFIGURATION FILE>"
};
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
var queueName = "nsw";
channel.QueueDeclare(queueName, false, false, false, null);
channel.QueueBind(queueName, "weather_topic", "aus.nsw.*");
The above code sets up a queue nsw
with a binding on the weather_topic
exchange with a binding key aus.nws.*
that filters all messages for NSW state in Australia.
To set up a Queue to capture all messages to Australia, let's create a new queue aus
with the binding using the # (hash) wildcard, as shown below.
var queueName = "aus";
channel.QueueDeclare(queueName, false, false, false, null);
channel.QueueBind(queueName, "weather_topic", "aus.#");
Whenever a message comes to the exchange for any state in Australia, a copy gets routed to the aus
queue. Similarly, when a message arrives for any city in nsw
, a copy gets sent to both aus
and nsw
queue.
Rahul Nath Newsletter
Join the newsletter to receive the latest updates in your inbox.