Skip to content

Commit 41940e7

Browse files
committed
feature #9757 [Messenger] Add the Envelope in the documentation (sroze, weaverryan)
This PR was merged into the 4.1 branch. Discussion ---------- [Messenger] Add the Envelope in the documentation Because we've merged this beautiful PR :) Commits ------- a87d727 Renaming variable 16c7385 Merge branch '4.1' into messenger-envelope dd8b368 Reword the header regarding the envelope 357fe25 Add message envelope in the documentation
2 parents 13f5c42 + a87d727 commit 41940e7

File tree

1 file changed

+68
-7
lines changed

1 file changed

+68
-7
lines changed

components/messenger.rst

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
98154
Transports
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

198260
To 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

Comments
 (0)