@@ -7,6 +7,9 @@ Please read the [Introduction](intro.md) before reading this provider documentat
7
7
- [ Configuration] ( #configuration )
8
8
- [ Producers] ( #producers )
9
9
- [ Consumers] ( #consumers )
10
+ - [ Routing Keys and Wildcard Support] ( #routing-keys-and-wildcard-support )
11
+ - [ Basic Routing Keys] ( #basic-routing-keys )
12
+ - [ Wildcard Routing Keys] ( #wildcard-routing-keys )
10
13
- [ Acknowledgment Mode] ( #acknowledgment-mode )
11
14
- [ Consumer Error Handling] ( #consumer-error-handling )
12
15
- [ Dead Letter Exchange] ( #dead-letter-exchange )
@@ -148,6 +151,79 @@ We can specify defaults for all consumers on the bus level:
148
151
});
149
152
```
150
153
154
+ #### Routing Keys and Wildcard Support
155
+
156
+ RabbitMQ routing keys are used by exchanges to determine which queues should receive a message. SlimMessageBus fully supports RabbitMQ's routing key semantics, including ** wildcard routing keys** for topic exchanges.
157
+
158
+ ##### Basic Routing Keys
159
+
160
+ For direct and topic exchanges, you can specify exact routing keys when binding consumers:
161
+
162
+ ``` cs
163
+ mbb .Consume <OrderEvent >(x => x
164
+ .Queue (" orders-queue" )
165
+ .ExchangeBinding (" orders-exchange" , routingKey : " orders.created" )
166
+ .WithConsumer <OrderCreatedConsumer >());
167
+ ```
168
+
169
+ ##### Wildcard Routing Keys
170
+
171
+ For topic exchanges, SlimMessageBus supports RabbitMQ's wildcard routing key patterns:
172
+
173
+ - ** ` * ` (asterisk)** - matches exactly one segment
174
+ - ** ` # ` (hash)** - matches zero or more segments
175
+ - Segments are separated by ` . ` (dot)
176
+
177
+ ** Examples:**
178
+
179
+ ``` cs
180
+ services .AddSlimMessageBus (mbb =>
181
+ {
182
+ // Producer sends messages with specific routing keys
183
+ mbb .Produce <RegionEvent >(x => x
184
+ .Exchange (" regions" , exchangeType : ExchangeType .Topic )
185
+ .RoutingKeyProvider ((m , p ) => $" regions.{m .Country }.cities.{m .City }" ));
186
+
187
+ // Consumer 1: Match all cities in North America
188
+ mbb .Consume <RegionEvent >(x => x
189
+ .Queue (" na-cities-queue" )
190
+ .ExchangeBinding (" regions" , routingKey : " regions.na.cities.*" ) // * matches exactly one city
191
+ .WithConsumer <NorthAmericaCitiesConsumer >());
192
+
193
+ // Consumer 2: Match all events in the regions exchange
194
+ mbb .Consume <RegionEvent >(x => x
195
+ .Queue (" all-regions-queue" )
196
+ .ExchangeBinding (" regions" , routingKey : " regions.#" ) // # matches zero or more segments
197
+ .WithConsumer <AllRegionsConsumer >());
198
+
199
+ // Consumer 3: Match all audit events with any number of segments
200
+ mbb .Consume <AuditEvent >(x => x
201
+ .Queue (" audit-queue" )
202
+ .ExchangeBinding (" audit" , routingKey : " audit.events.#" )
203
+ .WithConsumer <AuditConsumer >());
204
+
205
+ // Consumer 4: Complex pattern - match region events ending with specific pattern
206
+ mbb .Consume <RegionEvent >(x => x
207
+ .Queue (" region-reports-queue" )
208
+ .ExchangeBinding (" regions" , routingKey : " regions.*.reports.*" ) // matches regions.{country}.reports.{type}
209
+ .WithConsumer <RegionReportsConsumer >());
210
+ });
211
+ ```
212
+
213
+ ** Routing Key Pattern Examples:**
214
+
215
+ | Pattern | Matches | Doesn't Match |
216
+ | ---------| ---------| ---------------|
217
+ | ` regions.na.cities.* ` | ` regions.na.cities.toronto ` <br />` regions.na.cities.newyork ` | ` regions.na.cities ` (missing segment)<br />` regions.na.cities.toronto.downtown ` (extra segment) |
218
+ | ` audit.events.# ` | ` audit.events.users.signup ` <br />` audit.events.orders.placed ` <br />` audit.events ` | ` audit.users ` (wrong prefix) |
219
+ | ` orders.#.region.* ` | ` orders.processed.region.na ` <br />` orders.created.cancelled.region.eu ` <br />` orders.region.na ` | ` orders.processed.state.california ` (wrong pattern)<br />` orders.processed.region ` (missing final segment) |
220
+ | ` # ` | Any routing key | None (matches everything) |
221
+
222
+ ** Performance Note:** SlimMessageBus optimizes routing key matching by:
223
+ - Using exact matches first for better performance
224
+ - Only applying wildcard pattern matching when no exact match is found
225
+ - Caching routing key patterns for efficient lookup
226
+
151
227
#### Acknowledgment Mode
152
228
153
229
When a consumer processes a message from a RabbitMQ queue, it needs to acknowledge that the message was processed. RabbitMQ supports three types of acknowledgments out which two are available in SMB:
@@ -370,7 +446,7 @@ In RabbitMQ, the default exchange (sometimes referred to as the default direct e
370
446
371
447
- Its name is an empty string (`" " `).
372
448
- It is of type direct .
373
- - Every queue that you declare is automatically bound to this default exchange with a routing key equal to the queue ’ s name .
449
+ - Every queue that you declare is automatically bound to this default exchange with a routing key equal to the queue ' s name .
374
450
375
451
This means :
376
452
@@ -380,14 +456,14 @@ This will deliver the message straight to the `my_queue` queue.
380
456
381
457
### Why it exists
382
458
383
- The default exchange makes it easy to send messages directly to a queue without having to explicitly set up an exchange and binding . It ’ s often used for simple "Hello World " style examples and direct queue messaging .
459
+ The default exchange makes it easy to send messages directly to a queue without having to explicitly set up an exchange and binding . It ' s often used for simple "Hello World " style examples and direct queue messaging .
384
460
385
461
✅ **Key points to remember **
386
462
387
463
- The default exchange has no name (`" " `).
388
464
- Type : direct .
389
465
- Auto - binds every queue by its own name .
390
- - Messages published to it must use the queue ’ s name as the routing key .
466
+ - Messages published to it must use the queue ' s name as the routing key.
391
467
392
468
## Connection Resiliency
393
469
0 commit comments