Working With Bindings

About this guide

This guide covers bindings in AMQP 0.9.1, what they are, what role do they play and how to accomplish typical operations using Ruby amqp gem.

This work is licensed under a Creative Commons Attribution 3.0 Unported License (including images & stylesheets). The source is available on Github.

Covered versions

This guide covers Ruby amqp gem v0.8.0 and later.

Bindings in AMQP 0.9.1

Bindings are rules that exchanges use (among other things) to route messages to queues. To instruct an exchange E to route messages to a queue Q, Q has to be bound to E. Bindings may have an optional routing key attribute used by some exchange types. The purpose of the routing key is to selectively match only specific (matching) messages published to an exchange to the bound queue. In other words, the routing key acts like a filter.

Learn more about how bindings fit into the AMQP Model in the AMQP 0.9.1 Model Explained documentation guide.

What Are AMQP 0.9.1 Bindings

Bindings are rules that exchanges use (among other things) to route messages to queues. To instruct an exchange E to route messages to a queue Q, Q has to be bound to E. Bindings may have an optional routing key attribute used by some exchange types. The purpose of the routing key is to selectively match only specific (matching) messages published to an exchange to the bound queue. In other words, the routing key acts like a filter.

To draw an analogy:

Some exchange types use routing key while some others do not (and route messages unconditionally or based on message metadata). If AMQP message cannot be routed to any queue (for example, because there are no bindings for the exchange it was published to), it is either dropped or returned to the publisher, depending on message attributes the publisher has set.

If application wants to connect a queue to an exchange, it needs to bind them. The opposite operation is called unbinding.

Binding queues to exchanges

In order to receive messages, a queue needs to be bound to at least one exchange. Most of the time binding is explcit (done by applications). To bind a queue to an exchange, use AMQP::Queue#bind where the argument passed can be either an AMQP::Exchange instance or a string.


queue.bind(exchange) do |bind_ok|
  puts "Just bound #{queue.name} to #{exchange.name}"
end

Full example:

The same example using a string without callback:


queue.bind("amq.fanout")

Full example:

Unbinding queues from exchanges

To unbind a queue from an exchange use AMQP::Queue#unbind:


queue.unbind(exchange)

Full example:

Trying to unbind a queue from an exchange that the queue was never bound to will result in a channel-level exception.

Bindings, Routing and Returned Messages

How AMQP 0.9.1 Brokers Route Messages

After AMQP message reaches AMQP broker and before it reaches a consumer, several things happen:

A more in-depth description is this:

The takeaway is that messages may or may not be routed and it is important for applications to handle unroutable messages.

Handling of Unroutable Messages

Unroutable messages are either dropped or returned back to producers. Vendor-specific extensions can provide additional ways of handing of unroutable messages: for example, RabbitMQ’s Alternate Exchanges extension makes it possible to route unroutable messages to another exchange. amqp gem support for it is documented in the Vendor-specific Extensions guide.

RabbitMQ 2.6 will introduce a new feature callled dead letter queue where unroutable messages will be put instead of dropping them.

amqp gem provides a way to handle returned messages with the AMQP::Exchange#on_return method:


exchange.on_return do |basic_return, , payload|
  puts "#{payload} was returned! reply_code = #{basic_return.reply_code}, reply_text = #{basic_return.reply_text}"
end

Working With Exchanges documentation guide provides more information on the subject, including full code examples.

Authors

This guide was written by Michael Klishin and edited by Chris Duncan.

Tell us what you think!

Please take a moment and tell us what you think about this guide on Twitter or Ruby AMQP mailing list: 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