# Default, Direct and Fanout Exchanges — RabbitMQ

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

> Route messages with the default, direct and fanout exchange types.

## Three simple routing rules

Every vhost has a **default exchange** (named with the empty string `""`): every queue is automatically bound to it with its own name as the binding key, so publishing with `routing_key="emails"` delivers straight to the `emails` queue. It is convenient for simple work queues. A **direct exchange** delivers a message to every queue whose binding key **exactly equals** the routing key, so routing key `pdf` reaches the queue bound with `pdf`. Several queues may share a binding key, and each gets a copy. A **fanout exchange** ignores routing keys and copies every message to **all** bound queues: classic **publish-subscribe**, where each subscribing service has its own queue. Exchanges never store messages; if no queue matches, the message is dropped unless you use the **mandatory** flag or an **alternate exchange** to catch unroutable messages.

## Direct versus fanout routing

A direct exchange matches routing keys exactly; a fanout exchange copies to every bound queue.

![Left: a diamond with arrows to two of three queues based on matching labels. Right: a diamond with arrows to all three queues.](assets/figures/rabbitmq/section-2-map.svg) — Figure 2.1 — Direct and fanout exchanges.

## Fanout for broadcasting, direct for job types

Each subscriber declares its own queue and binds it.

```python
# publish-subscribe: every service gets its own copy of user events
channel.exchange_declare("user.events", exchange_type="fanout", durable=True)
for q in ("crm.user-events", "analytics.user-events", "email.user-events"):
    channel.queue_declare(q, durable=True, arguments={"x-queue-type": "quorum"})
    channel.queue_bind(q, "user.events")              # routing key ignored

# direct: route jobs by type
channel.exchange_declare("jobs", exchange_type="direct", durable=True)
channel.queue_declare("jobs.pdf", durable=True)
channel.queue_bind("jobs.pdf", "jobs", routing_key="pdf")
channel.basic_publish("jobs", routing_key="pdf", body=b'{"invoiceId": 7}')
```

## Catch unroutable messages

A typo in a routing key silently drops messages. Configure an alternate exchange on important exchanges, or publish with `mandatory=True` and handle returned messages.

**Quiz:** Three services must each receive every UserRegistered message. Which setup fits best?

- [ ] One queue shared by all three services
- [ ] The default exchange with one queue
- [x] A fanout (or topic) exchange with a separate queue per service
- [ ] A direct exchange with no bindings

*Answer:* A fanout (or topic) exchange with a separate queue per service. Each service needs its own queue bound to the exchange so it gets its own copy.
