@@ -95,6 +95,62 @@ that will do the required processing for your message::
9595 }
9696 }
9797
98+ Adding Metadata to Messages (Envelopes)
99+ ---------------------------------------
100+
101+ If you need to add metadata or some configuration to a message, wrap it with the
102+ :class: `Symfony\\ Component\\ Messenger\\ Envelope ` class. For example, to set the
103+ serialization groups used when the message goes through the transport layer, use
104+ the ``SerializerConfiguration `` envelope::
105+
106+ use Symfony\Component\Messenger\Envelope;
107+ use Symfony\Component\Messenger\Transport\Serialization\SerializerConfiguration;
108+
109+ $bus->dispatch(
110+ (new Envelope($message))->with(new SerializerConfiguration([
111+ 'groups' => ['my_serialization_groups'],
112+ ]))
113+ );
114+
115+ At the moment, the Symfony Messenger has the following built-in envelopes:
116+
117+ 1. :class: `Symfony\\ Component\\ Messenger\\ Transport\\ Serialization\\ SerializerConfiguration `,
118+ to configure the serialization groups used by the transport.
119+ 2. :class: `Symfony\\ Component\\ Messenger\\ Middleware\\ Configuration\\ ValidationConfiguration `,
120+ to configure the validation groups used when the validation middleware is enabled.
121+ 3. :class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Transport\\ ReceivedMessage `,
122+ an internal item that marks the message as received from a transport.
123+
124+ Instead of dealing directly with the messages in the middleware you can receive the
125+ envelope by implementing the :class: `Symfony\\ Component\\ Messenger\\ EnvelopeAwareInterface `
126+ marker, like this::
127+
128+ use Symfony\Component\Messenger\Asynchronous\Transport\ReceivedMessage;
129+ use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
130+ use Symfony\Component\Messenger\EnvelopeAwareInterface;
131+
132+ class MyOwnMiddleware implements MiddlewareInterface, EnvelopeAwareInterface
133+ {
134+ public function handle($envelope, callable $next)
135+ {
136+ // $envelope here is an `Envelope` object, because this middleware
137+ // implements the EnvelopeAwareInterface interface.
138+
139+ if (null !== $envelope->get(ReceivedMessage::class)) {
140+ // Message just has been received...
141+
142+ // You could for example add another item.
143+ $envelope = $envelope->with(new AnotherEnvelopeItem(/* ... */));
144+ }
145+
146+ return $next($envelope);
147+ }
148+ }
149+
150+ The above example will forward the message to the next middleware with an additional
151+ envelope item *if * the message has just been received (i.e. has the `ReceivedMessage ` item).
152+ You can create your own items by implementing :class: `Symfony\\ Component\\ Messenger\\ EnvelopeAwareInterface `.
153+
98154Transports
99155----------
100156
@@ -115,6 +171,7 @@ First, create your sender::
115171
116172 use App\Message\ImportantAction;
117173 use Symfony\Component\Messenger\Transport\SenderInterface;
174+ use Symfony\Component\Messenger\Envelope;
118175
119176 class ImportantActionToEmailSender implements SenderInterface
120177 {
@@ -127,10 +184,12 @@ First, create your sender::
127184 $this->toEmail = $toEmail;
128185 }
129186
130- public function send($message )
187+ public function send(Envelope $envelope )
131188 {
189+ $message = $envelope->getMessage();
190+
132191 if (!$message instanceof ImportantAction) {
133- throw new \InvalidArgumentException(sprintf('Producer only supports "%s" messages.', ImportantAction::class));
192+ throw new \InvalidArgumentException(sprintf('This transport only supports "%s" messages.', ImportantAction::class));
134193 }
135194
136195 $this->mailer->send(
@@ -165,6 +224,7 @@ First, create your receiver::
165224 use App\Message\NewOrder;
166225 use Symfony\Component\Messenger\Transport\ReceiverInterface;
167226 use Symfony\Component\Serializer\SerializerInterface;
227+ use Symfony\Component\Messenger\Envelope;
168228
169229 class NewOrdersFromCsvFile implements ReceiverInterface
170230 {
@@ -182,7 +242,9 @@ First, create your receiver::
182242 $ordersFromCsv = $this->serializer->deserialize(file_get_contents($this->filePath), 'csv');
183243
184244 foreach ($ordersFromCsv as $orderFromCsv) {
185- $handler(new NewOrder($orderFromCsv['id'], $orderFromCsv['account_id'], $orderFromCsv['amount']));
245+ $order = new NewOrder($orderFromCsv['id'], $orderFromCsv['account_id'], $orderFromCsv['amount']);
246+
247+ $handler(new Envelope($order));
186248 }
187249 }
188250
@@ -196,10 +258,9 @@ Receiver and Sender on the same Bus
196258~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
197259
198260To allow sending and receiving messages on the same bus and prevent an infinite
199- loop, the message bus is equipped with the ``WrapIntoReceivedMessage `` middleware.
200- It will wrap the received messages into ``ReceivedMessage `` objects and the
201- ``SendMessageMiddleware `` middleware will know it should not route these
202- messages again to a transport.
261+ loop, the message bus will add a :class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Transport\\ ReceivedMessage `
262+ envelope item to the message envelopes and the :class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Middleware\\ SendMessageMiddleware `
263+ middleware will know it should not route these messages again to a transport.
203264
204265.. _blog posts about command buses : https://matthiasnoback.nl/tags/command%20bus/
205266.. _SimpleBus project : http://simplebus.io
0 commit comments