Skip to content

Wire level format of messages

ldeluigi edited this page Apr 12, 2023 · 11 revisions
Clone this wiki locally

A Rebus message contains the following two things:

  • message headers - list of key/value pairs, both are strings
  • message body - an object

This page will describe the two on a general level - you can read more about the concrete details on the page of each of the supported transports: MSMQ transport, RabbitMQ transport, Azure Service Bus transport.

Message headers

Rebus message headers should be moved in a way that makes them visible to the outside, allowing them to be used to contain various metadata about the message, which turns out can be used for various conveninent purposes.

If the transport has a mechanism for transferring headers, that mechanism should be used (if not for all headers, then at least in a way that makes relevant headers visible to applications and tools that don't necessarily know anything about Rebus).

Rebus has a number of special headers that carry with them special semantics, and these will be used by Rebus to e.g. implement the ability to reply back to the sender of a message, etc. All special Rebus headers are prefixed with rbs2-, e.g. rbs2-correlation-id to denote the automatically-flowing correlation ID that can be used to track cause and effect in your endpoints.

All the special Rebus headers are described in more detail in the code.

You can of course attach your own custom headers to messages (by using the optional Dictionary<string,string> parameter of Send/Publish etc.), thus allowing you to pass your own metadata along with messages. Many of the special Rebus headers can be set as well (e.g. rbs2-return-address, in order to have the reply sent to another endpoint than the requestor), but you should be careful to test that you get the expected behavior.

Message body

Since most (if not all) transports support the basic transfer of raw bytes, this is what Rebus message bodies are transferred as. It is up to your chosen message serializer to convert a TransportMessage instance into a byte[], and then at the receiving end to convert the received byte[] back into a TransportMessage.

If the serializer is nice, it will add a rbs2-content-type header to the transport message, allowing you to write specialized tools that can inspect message contents no matter how they are serialized.

Rebus' default serializer, the built-in JSON serializer, is nice enough to do that. Other serializers might not do that.


This message is a simple class called Work containing an integer value WorkId and an array of strings named SomeValues - it's been sent from a one-way client (i.e. there's no rbs2-return-address header for replies), and the message body is UTF8-encoded JSON.