@@ -86,6 +86,65 @@ that will do the required processing for your message::
8686 }
8787 }
8888
89+ Envelope
90+ --------
91+
92+ The notion of an envelope is a concept that helps add context around the
93+ messages. An envelope is a message and a set of data. From a user's perspective, this
94+ allows you to set some configuration around the message. For example, to set the serialization
95+ groups used when the message goes through the transport layer, wrap your message
96+ in an ``Envelope `` and add some ``SerializerConfiguration ``::
97+
98+ use Symfony\Component\Messenger\Envelope;
99+ use Symfony\Component\Messenger\Transport\Serialization\SerializerConfiguration;
100+
101+ $bus->dispatch(
102+ (new Envelope($message))->with(new SerializerConfiguration([
103+ 'groups' => ['my_serialization_groups'],
104+ ]))
105+ );
106+
107+ At the moment, the Symfony Messenger has the following built-in envelopes:
108+
109+ 1.:class: `Symfony\\ Component\\ Messenger\\ Transport\\ Serialization\\ SerializerConfiguration `,
110+ to configure the serialization groups used by the transport.
111+ 2.:class: `Symfony\\ Component\\ Messenger\\ Middleware\\ Configuration\\ ValidationConfiguration `,
112+ to configure the validation groups used when the validation middleware is enabled.
113+ 3.:class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Transport\\ ReceivedMessage `,
114+ an internal item that marks the message as received from a transport.
115+
116+ Instead of dealing directly with the messages in the middleware you can receive the
117+ envelope by implementing the:class: `Symfony\\ Component\\ Messenger\\ EnvelopeAwareInterface `
118+ marker, like this::
119+
120+ use Symfony\Component\Messenger\Asynchronous\Transport\ReceivedMessage;
121+ use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
122+ use Symfony\Component\Messenger\EnvelopeAwareInterface;
123+
124+ class MyOwnMiddleware implements MiddlewareInterface, EnvelopeAwareInterface
125+ {
126+ public function handle($message, callable $next)
127+ {
128+ // $message here is an `Envelope` object, because this middleware
129+ // implements the EnvelopeAwareInterface interface. Otherwise,
130+ // it would be the "original" message.
131+
132+ if (null !== $message->get(ReceivedMessage::class)) {
133+ // Message just has been received...
134+
135+ // You could for example add another item.
136+ $message = $message->with(new AnotherEnvelopeItem(/* ... */));
137+ }
138+
139+ return $next($message);
140+ }
141+ }
142+
143+ The above example will forward the message to the next middleware with an additional
144+ envelope item if the message has just been received (i.e. has the `ReceivedMessage ` item).
145+ You can create your own items by implementing the:class: `Symfony\\ Component\\ Messenger\\ EnvelopeAwareInterface `
146+ interface.
147+
89148Transports
90149----------
91150
@@ -106,6 +165,7 @@ First, create your sender::
106165
107166 use App\Message\ImportantAction;
108167 use Symfony\Component\Messenger\Transport\SenderInterface;
168+ use Symfony\Component\Messenger\Envelope;
109169
110170 class ImportantActionToEmailSender implements SenderInterface
111171 {
@@ -118,10 +178,12 @@ First, create your sender::
118178 $this->toEmail = $toEmail;
119179 }
120180
121- public function send($message )
181+ public function send(Envelope $envelope )
122182 {
183+ $message = $envelope->getMessage();
184+
123185 if (!$message instanceof ImportantAction) {
124- throw new \InvalidArgumentException(sprintf('Producer only supports "%s" messages.', ImportantAction::class));
186+ throw new \InvalidArgumentException(sprintf('This transport only supports "%s" messages.', ImportantAction::class));
125187 }
126188
127189 $this->mailer->send(
@@ -156,6 +218,7 @@ First, create your receiver::
156218 use App\Message\NewOrder;
157219 use Symfony\Component\Messenger\Transport\ReceiverInterface;
158220 use Symfony\Component\Serializer\SerializerInterface;
221+ use Symfony\Component\Messenger\Envelope;
159222
160223 class NewOrdersFromCsvFile implements ReceiverInterface
161224 {
@@ -173,7 +236,9 @@ First, create your receiver::
173236 $ordersFromCsv = $this->serializer->deserialize(file_get_contents($this->filePath), 'csv');
174237
175238 foreach ($ordersFromCsv as $orderFromCsv) {
176- $handler(new NewOrder($orderFromCsv['id'], $orderFromCsv['account_id'], $orderFromCsv['amount']));
239+ $order = new NewOrder($orderFromCsv['id'], $orderFromCsv['account_id'], $orderFromCsv['amount']);
240+
241+ $handler(new Envelope($order));
177242 }
178243 }
179244
@@ -187,7 +252,6 @@ Receiver and Sender on the same Bus
187252~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
188253
189254To allow sending and receiving messages on the same bus and prevent an infinite
190- loop, the message bus is equipped with the ``WrapIntoReceivedMessage `` middleware.
191- It will wrap the received messages into ``ReceivedMessage `` objects and the
192- ``SendMessageMiddleware `` middleware will know it should not route these
193- messages again to a transport.
255+ loop, the message bus will add a:class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Transport\\ ReceivedMessage `
256+ envelope item to the message envelopes and the:class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Middleware\\ SendMessageMiddleware `
257+ middleware will know it should not route these messages again to a transport.