Patterns and Use Cases

This Documentation Has Moved to rubyamqp.info

amqp gem documentation guides are now hosted on rubyamqp.info.

About this guide

This guide explains typical messaging patterns and use cases. It only covers the most common scenarios. For comprehensive list of messaging patterns, consult books on this subject, for example, Enterprise Integration Patterns.

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.

Introduction

Messaging patterns are a lot like object-oriented design patterns: they are generalized reusable solutions to specific problems. They are not recipes, however, and their exact implementation may and will vary from application to application. Just like OO design patterns, they can classified:

There are other, more specialized group of messaging patterns that are out of scope of this guide.

This guide demonstrates implementation of several common routing patterns plus explains how built-in AMQP 0.9.1 features can be used to implement message construction and message transformation patterns.

Note that guide is a work in progress. There are many messaging patterns and new variations are being discovered every year. This guide thus strives to be useful to the 80% of developers instead of being “complete”.

Request/Reply pattern

Description & Use cases

Request/Reply is a simple way of integration when one application issues a request and another application responds to it. This pattern is often referred to as"Remote Procedure Call", even when it is not entirely correct. Request/Reply pattern is a 1:1 communication pattern.

Some examples of Request/Reply pattern are:

AMQP-based implementation

Implementation of Request/Reply pattern on top of AMQP 0.9.1 involves two messages: a request (Req) and a response (Res). Client app generates a request identifier and sets :message_id attribute on Req. Client also uses a server-named exclusive queue to receive replies and thus sets :reply_to Req attribute to the name of that queue.

Server app uses a well-known queue name to receive requests and sets :correlation_id to :message_id of the original request message (Req) to make it possible for the client to identify what request this reply is for.

Request message attributes

:message_id
Unique message identifier
:reply_to
Queue name server should send the response to

Response message attributes

:correlation_id
Identifier of the original request message (set to request’s :correlation_id)
:routing_key
Client’s replies queue name (set to request’s :reply_to)

Code example

Client code

Server code

In the examples above messages are published with the :immediate attribute set. This is not necessary in all cases: sometimes it is OK for requests to sit in the queue without active consumers. Replies, on the other hand, assume an active consumer and existing replies queue, so if routing or immediate delivery do not succeed, server application will log returned messages. More on this in the Working With Exchanges guide.

Related patterns

Request/Reply demonstrates two common techniques that are sometimes referred to as messaging patterns of its own:

Other related patterns are

Command pattern

Description & Use cases

Command pattern is very similar to Request/Reply, except that there is no reply and messages are typed. For example, most modern Web applications have at least one “background task processor” that carries out a number of operations asynchronously, without sending any responses back. Command pattern usually assumes 1:1 communication.

Some specific examples of Command pattern are:

AMQP-based implementation

Implementation of Command pattern on top of AMQP 0.9.1 involves well-known durable queues. Application that issues the command then can use default exchange to publish messages to well-known services directly. Request message :type attribute then indicates command type and message body (or body and headers) carry additional information consumer needs to carry it out.

Request message attributes

:type
Message type as a string. For example: gems.install or commands.shutdown

Code example

Producer (Sender)

Consumer (Recipient)

Related patterns

Event pattern

Description & Use cases

Event pattern is a version of the Command pattern, but with 1 or more receivers (1:N communication). The world we live in is full of events, so applications of this pattern are endless.

Some specific use cases of Event pattern are

The Event pattern is very similar to the Command pattern, however, there is typically certain differences between the two:

AMQP-based implementation

Because Event pattern is a 1:N communication pattern, it typically uses a fanout exchange. Event listeners then use server-named exclusive queues and all bind to that exchange. Event messages use :type message attribute to indicate event type and message body (plus, possibly, message headers) to pass event context information.

Request message attributes

:type
Message type as a string. For example: files.created, files.indexed or pages.viewed

Due to misconfiguration or different upgrade time/policy, applications may receive events they do not know how to handle. It is important for developers to handle such cases, otherwise it is likely that consumers may crash.

More on fanout exchange type in the Working With Exchanges guide.

Code example

Producer (Sender)

Consumer (Handler)

Related patterns

Document Message pattern

Description & Use cases

Document Message pattern is very similar to Command and Event patterns. The difference is in the intent: whereas a Command message tells the receiver to invoke certain behavior, a Document Message just passes data and lets the receiver decide what, if anything, to do with the data.

Message payload is a single logical entity, for example, one (or a group of closely related) database rows or documents.

Use cases for the Document Message pattern often have something to do with processing of documents:

Competing Consumers pattern

Description & Use cases

Competing Consumers are multiple consumers that process messages from a shared queue.

TBD

AMQP-based implementation

TBD

Code example

TBD

Publish/Subscribe pattern

Description & Use cases

TBD

AMQP-based implementation

TBD

Code example

TBD

Scatter/Gather pattern

Description & Use cases

TBD

AMQP-based implementation

TBD

Code example

TBD

Smart Proxy pattern

Description & Use cases

TBD

AMQP-based implementation

TBD

Code example

TBD

Multistep Processing (Routing Slip) pattern

Description & Use cases

TBD

AMQP-based implementation

TBD

Code example

TBD

Authors

These guides were 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