# @title Ruby AMQP gem: Working with exchanges h1. Working with exchanges h2. About this guide This guide covers everything related to exchanges in AMQP 0.9.1, common usage scenarios and how to accomplish typical operations using amqp gem. h2. Covered versions This guide covers "Ruby amqp gem":http://github.com/ruby-amqp/amqp v0.8.0 and later. h2. Exchanges in AMQP 0.9.1, briefly h3. What are AMQP exchanges? An exchange accepts messages from a producer application and routes these to message queues. They can be thought of as "mailboxes" of AMQP world. Unlike some other messaging middleware products and protocols, in AMQP messages are *not* published directly to queues: they are published to exchanges that route them to queue(s) using pre-arranged criteria (called bindings). There are multiple exchange types in AMQP 0.9.1, each with its own routing semantics. Custom exchange types can be created to cover sophisticated routing scenarios (for example, routing based on geolocation data), edge cases or just for convenience. h3. Concept of bindings Binding is an association between a queue and an exchange. Queues must be bound to at least one exchange in order to receive messages from publishers. Learn more about bindings in {file:docs/Bindings.textile Bindings guide}. h3. Attributes Exchanges have several attributes associated with them: * Name * Type (direct, fanout, topic, headers or some custom type) * Durability * Whether exchange is auto-deleted when no longer used * Other metadata (aka X-arguments) h2. Exchange types There are 4 built-in exchange types in AMQP 0.9.1: * Direct * Fanout * Topic * Headers As stated previously, each exchange type has own routing semantics and new exchange types can be added by extending brokers with plugins. Custom exchange types begin with x-, much like custom HTTP headers, for example, "x-recent-history exchange":https://github.com/videlalvaro/rabbitmq-recent-history-exchange. h2. Message attributes Before we start looking at various exchange types and their routing semantics, we need to introduce idea of message attributes. Every AMQP message has a number of *attributes*. Some attributes are important and used very often, other are used rarely. AMQP message attributes are metadata: they are similar in purpose to HTTP request and response headers. Every AMQP 0.9.1 message has an attribute called the *routing key*. The routing key is an "address" that the exchange may use to decide how to route the message (similar to, but more generic, than URL in HTTP). Most exchange types use routing key to implement routing logic, but some ignore it and use other criteria (for example, message content). h2. Fanout exchanges Fanout exchanges route messages to all queues bound to it, 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, so fanout exchanges are ideal for "broadcast routing":http://en.wikipedia.org/wiki/Broadcasting_%28computing%29 of messages. Graphically this can be represented as !http://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Broadcast.svg/500px-Broadcast.svg.png! AMQP 0.9.1 brokers must implement fanout exchange type and pre-declare one instance with the name of "amq.fanout". This means that applications can rely on that exchange to always be available to them. Each vhost has a separate instance of that exchange, it is *not shared across vhosts* for obvious reasons. h2. Direct exchanges Direct exchange delivers messages to queues based on *message routing key*, an attribute every AMQP 0.9.1 message has. Here is how it works: * A queue binds to the exchange with a routing key, K. * When a new message with routing key R arrives to direct exchange, the exchange routes it to the queue if K = R. Direct exchange is ideal for "unicast routing":http://en.wikipedia.org/wiki/Unicast of messages (although it can be used for "multicast routing":http://en.wikipedia.org/wiki/Multicast, too). !http://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Unicast.svg/500px-Unicast.svg.png! AMQP 0.9.1 brokers must implement direct exchange type and pre-declare two instances * *amq.direct*. * *""* (unnamed, referred to as an empty string by many clients including amqp Ruby gem) exchange known as *default exchange*. This means that applications can rely on those exchanges to always be available to them. Each vhost has separate instances of those exchanges, they are *not shared across vhosts* for obvious reasons. h3. Default exchange Default exchange is a direct exchange with no name (amqp gem refers to it using an empty string) pre-declared by the broker. It has one key special property that makes it very useful for simple applications: *every queue is automatically bound to it with a routing key the same as queue name". For example, when you declare a queue with the name of "search.indexing.online", AMQP broker will bind it to the default exchange using "search.indexing.online" as routing key. So a message publishes to the default exchange with routing key = "search.indexing.online" will be routed to the queue "search.indexing.online". In other words, default exchange makes it possible to "deliver messages directly to queues", even though that is not technically correct. amqp gem offers two ways of obtaining of the default exchange: {AMQP::Channel#default_exchange} and {AMQP::Channel#direct} (use empty string as exchange name). {AMQP::Exchange#initialize} can be used as well but requires more effort and for this particular case offers no benefits over instance methods on {AMQP::Channel}. The default exchange is what the "Hello, World" example uses: {include:file:examples/hello_world.rb} h2. Topic exchanges Topic exchanges route messages to one or many queues based on matching between message routing key and pattern that was used for binding queue to the exchange. Topic exchanges are commonly used for "multicast routing":http://en.wikipedia.org/wiki/Multicast of messages. !http://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Multicast.svg/500px-Multicast.svg.png! Topic exchanges can be used for "broadcast routing":http://en.wikipedia.org/wiki/Broadcasting_%28computing%29 but usually fanout exchanges are more efficient at that. Here is an example of topic exchange in action: {include:file:examples/routing/weather_updates.rb} TBD h2. Headers exchanges TBD h2. Custom exchange types TBD h2. Declaring/Instantiating exchanges Below is an example of {AMQP::Exchange#initialize} used with a callback: {include:file:examples/exchanges/declare_an_exchange_without_assignment.rb} TBD h2. Publishing messages h3. Publishing one-off messages The following example publishes a message and *safely* closes AMQP connection after that by passing a block to {AMQP::Exchange#publish}: {include:file:examples/publishing/publishing_a_one_off_message.rb} TBD h2. Binding queues to exchanges TBD h2. Unbinding queues from exchanges TBD h2. Deleting exchanges Exchanges are be *auto-deleted*. An example that uses two auto-deleted exchanges: {include:file:examples/exchanges/autodeletion_of_exchanges.rb} TBD h2. Exchange durability vs Message durability See {file:docs/Durability.textile Durability guide} h2. Error handling and recovery TBD h2. Vendor-specific extensions related to exchanges See {file:docs/VendorSpecificExtensions.textile Vendor-specific Extensions guide} h2. What to read next TBD h2. Tell us what you think! Please take a moment and tell us what you think about this guide on "Ruby AMQP mailing list":http://groups.google.com/group/ruby-amqp: what was unclear? what wasn't covered? maybe you don't like guide style or grammar and spelling are incorrect? Readers feedback is key to making documentation better. If mailing list communication is not an option for you for some reason, you can "contact guides author directly":mailto:michael@novemberain.com?subject=amqp%20gem%20documentation