# Topic and Headers Exchanges — RabbitMQ

Source: https://www.skillbyai.com/en/rabbitmq/e-topic

> Use topic wildcards and header matching for flexible routing.

## Pattern-based routing

A **topic exchange** routes by matching the routing key against binding patterns. Routing keys are words separated by dots, such as `order.placed.in` or `payment.failed.card`. In binding patterns, **`*`** matches **exactly one word** and **`#`** matches **zero or more words**. So `order.*.in` matches `order.placed.in` but not `order.placed`; `order.#` matches everything starting with `order`; and `#` alone matches every message, behaving like fanout. Topic exchanges are the most common choice for **event routing**: producers publish descriptive keys, and each consumer binds the patterns it cares about. A **headers exchange** ignores the routing key and matches on message **header** values, with `x-match` set to `all` (every listed header must match) or `any` (at least one). Headers exchanges are useful when routing depends on several attributes, but topic exchanges are simpler and more widely used.

## Topic bindings for an orders exchange

Each consumer chooses the subset of events it needs.

```python
channel.exchange_declare("orders", exchange_type="topic", durable=True)

bindings = {
    "billing.orders":      ["order.placed.*", "order.cancelled.*"],
    "india-ops.orders":    ["order.*.in"],              # all Indian order events
    "audit.orders":        ["order.#"],                  # everything about orders
}
for queue, patterns in bindings.items():
    channel.queue_declare(queue, durable=True, arguments={"x-queue-type": "quorum"})
    for p in patterns:
        channel.queue_bind(queue, "orders", routing_key=p)

channel.basic_publish("orders", "order.placed.in", body=b'{"orderId": "o-1001"}')
# delivered to billing.orders, india-ops.orders and audit.orders
```

## Mail sorting by postcode

A topic pattern is like a sorter that says "anything starting with 400 goes to Mumbai" (`400.#`) or "any single-digit district in 560" (`560.*`). Senders write full addresses; sorters decide the coverage.

**Quiz:** Which routing key matches the binding pattern `order.*.in`?

- [ ] order.placed
- [x] order.placed.in
- [ ] order.placed.express.in
- [ ] payment.placed.in

*Answer:* order.placed.in. `*` matches exactly one word, so only `order.placed.in` fits.
