# Introduction to Exchanges

* Exchanges are AMQP entities where messages are sent to.
* Exchanges take a message and route it into zero or more queues.
* The routing algorithm used depends on the exchange type and rules called bindings.
*   AMQP 0-9-1 brokers provide four exchange types:

    | Exchange Type    | Default Pre-declared names                |
    | ---------------- | ----------------------------------------- |
    | Direct exchange  | (Empty string) and amq.direct             |
    | Fanout exchange  | amq.fanout                                |
    | Topic exchange   | amq.topic                                 |
    | Headers exchange | amq.match _(and amq.headers in RabbitMQ)_ |
* Exchanges are declared with a number of attributes, the most important of which are:
  * Name
  * Durability _(exchanges survive broker restart)_
  * Auto-delete _(exchange is deleted when last queue is unbound from it)_
  * Arguments _(optional, used by plugins and broker-specific features)_
* Exchanges can be durable or transient.
  * Durable exchanges survive broker restart whereas transient exchanges do not _(they have to be redeclared when broker comes back online)_.
  * Not all scenarios and use cases require exchanges to be durable.

## [Default Exchanges](https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-default)

* The default exchange is a direct exchange with no name (empty string) pre-declared by the broker.
* This makes it ideal for simple applications, every queue that is created is automatically bound to it by the messsage broker with a routing key which is the same as the queue name.
* The default exchange makes it seem like it is possible to deliver messages directly to queues, even though that is not technically what is happening.

## [Direct Exchanges](https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-direct)

* A direct exchange delivers messages to queues based on the message routing key.
* A direct exchange is ideal for the unicast routing of messages. They can be used for multicast routing as well.
* Working of direct exchanges,
  * A queue binds to the exchange with a routing key `K`.
  * When a new message with routing key `R` arrives at the direct exchange, the exchange routes it to the queue, if `K = R`.
  * If multiple queues are bound to a direct exchange with the same routing key `K`, the exchange will route the message to all queues for which `K = R`.

## [Fanout Exchanges](https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-fanout)

* A fanout exchange routes messages to all of the queues that are bound to it and the routing key is ignored.
* If `N` queues are bound to a fanout exchange, when a new message is published to that exchange a copy of the message is delivered to all `N` queues. Fanout exchanges are ideal for the broadcast routing of messages.

## [Topic Exchanges](https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-topic)

* Topic exchanges route messages to one or many queues based on matching between a message routing key and the pattern that was used to bind a queue to an exchange.
* The topic exchange type is often used to implement various publish/subscribe pattern variations.
* Topic exchanges are commonly used for the multicast routing of messages.
* Whenever a problem involves multiple consumers/applications that selectively choose which type of messages they want to receive, the use of topic exchanges should be considered.

## [Headers Exchanges](https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-headers)

* A headers exchange is designed for routing on multiple attributes that are more easily expressed as message headers than a routing key.
* Headers exchanges ignore the routing key attribute.
* The attributes used for routing are taken from the headers attribute.
* A message is considered matching if the value of the header equals the value specified upon binding.
* Headers exchanges can be looked upon as "direct exchanges on steroids".
* Because they route based on header values, they can be used as direct exchanges where the routing key does not have to be a string; it could be an integer or a hash _(dictionary)_ for example.

## Learn more

* [Understanding Exchanges](https://www.cloudamqp.com/blog/part4-rabbitmq-for-beginners-exchanges-routing-keys-bindings.html)
