@@ -89,6 +89,65 @@ that will do the required processing for your message::
8989 }
9090 }
9191
92+ Envelope
93+ --------
94+
95+ The notion of an envelope is a concept that helps add context around the
96+ messages. An envelope is a message and a set of data. From a user's perspective, this
97+ allows you to set some configuration around the message. For example, to set the serialization
98+ groups used when the message goes through the transport layer, wrap your message
99+ in an ``Envelope `` and add some ``SerializerConfiguration ``::
100+
101+ use Symfony\Component\Messenger\Envelope;
102+ use Symfony\Component\Messenger\Transport\Serialization\SerializerConfiguration;
103+
104+ $bus->dispatch(
105+ (new Envelope($message))->with(new SerializerConfiguration([
106+ 'groups' => ['my_serialization_groups'],
107+ ]))
108+ );
109+
110+ At the moment, the Symfony Messenger has the following built-in envelopes:
111+
112+ 1. :class: `Symfony\\ Component\\ Messenger\\ Transport\\ Serialization\\ SerializerConfiguration `,
113+ to configure the serialization groups used by the transport.
114+ 2. :class: `Symfony\\ Component\\ Messenger\\ Middleware\\ Configuration\\ ValidationConfiguration `,
115+ to configure the validation groups used when the validation middleware is enabled.
116+ 3. :class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Transport\\ ReceivedMessage `,
117+ an internal item that marks the message as received from a transport.
118+
119+ Instead of dealing directly with the messages in the middleware you can receive the
120+ envelope by implementing the :class: `Symfony\\ Component\\ Messenger\\ EnvelopeAwareInterface `
121+ marker, like this::
122+
123+ use Symfony\Component\Messenger\Asynchronous\Transport\ReceivedMessage;
124+ use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
125+ use Symfony\Component\Messenger\EnvelopeAwareInterface;
126+
127+ class MyOwnMiddleware implements MiddlewareInterface, EnvelopeAwareInterface
128+ {
129+ public function handle($message, callable $next)
130+ {
131+ // $message here is an `Envelope` object, because this middleware
132+ // implements the EnvelopeAwareInterface interface. Otherwise,
133+ // it would be the "original" message.
134+
135+ if (null !== $message->get(ReceivedMessage::class)) {
136+ // Message just has been received...
137+
138+ // You could for example add another item.
139+ $message = $message->with(new AnotherEnvelopeItem(/* ... */));
140+ }
141+
142+ return $next($message);
143+ }
144+ }
145+
146+ The above example will forward the message to the next middleware with an additional
147+ envelope item if the message has just been received (i.e. has the `ReceivedMessage ` item).
148+ You can create your own items by implementing the :class: `Symfony\\ Component\\ Messenger\\ EnvelopeAwareInterface `
149+ interface.
150+
92151Transports
93152----------
94153
@@ -109,6 +168,7 @@ First, create your sender::
109168
110169 use App\Message\ImportantAction;
111170 use Symfony\Component\Messenger\Transport\SenderInterface;
171+ use Symfony\Component\Messenger\Envelope;
112172
113173 class ImportantActionToEmailSender implements SenderInterface
114174 {
@@ -121,10 +181,12 @@ First, create your sender::
121181 $this->toEmail = $toEmail;
122182 }
123183
124- public function send($message )
184+ public function send(Envelope $envelope )
125185 {
186+ $message = $envelope->getMessage();
187+
126188 if (!$message instanceof ImportantAction) {
127- throw new \InvalidArgumentException(sprintf('Producer only supports "%s" messages.', ImportantAction::class));
189+ throw new \InvalidArgumentException(sprintf('This transport only supports "%s" messages.', ImportantAction::class));
128190 }
129191
130192 $this->mailer->send(
@@ -159,6 +221,7 @@ First, create your receiver::
159221 use App\Message\NewOrder;
160222 use Symfony\Component\Messenger\Transport\ReceiverInterface;
161223 use Symfony\Component\Serializer\SerializerInterface;
224+ use Symfony\Component\Messenger\Envelope;
162225
163226 class NewOrdersFromCsvFile implements ReceiverInterface
164227 {
@@ -176,7 +239,9 @@ First, create your receiver::
176239 $ordersFromCsv = $this->serializer->deserialize(file_get_contents($this->filePath), 'csv');
177240
178241 foreach ($ordersFromCsv as $orderFromCsv) {
179- $handler(new NewOrder($orderFromCsv['id'], $orderFromCsv['account_id'], $orderFromCsv['amount']));
242+ $order = new NewOrder($orderFromCsv['id'], $orderFromCsv['account_id'], $orderFromCsv['amount']);
243+
244+ $handler(new Envelope($order));
180245 }
181246 }
182247
@@ -190,11 +255,9 @@ Receiver and Sender on the same Bus
190255~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191256
192257To allow sending and receiving messages on the same bus and prevent an infinite
193- loop, the message bus is equipped with the ``WrapIntoReceivedMessage `` middleware.
194- It will wrap the received messages into ``ReceivedMessage `` objects and the
195- ``SendMessageMiddleware `` middleware will know it should not route these
196- messages again to a transport.
197-
258+ loop, the message bus will add a :class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Transport\\ ReceivedMessage `
259+ envelope item to the message envelopes and the :class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Middleware\\ SendMessageMiddleware `
260+ middleware will know it should not route these messages again to a transport.
198261
199262.. _blog posts about command buses : https://matthiasnoback.nl/tags/command%20bus/
200263.. _SimpleBus project : http://simplebus.io
0 commit comments