@@ -95,6 +95,62 @@ that will do the required processing for your message::
95
95
}
96
96
}
97
97
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
+
98
154
Transports
99
155
----------
100
156
@@ -115,6 +171,7 @@ First, create your sender::
115
171
116
172
use App\Message\ImportantAction;
117
173
use Symfony\Component\Messenger\Transport\SenderInterface;
174
+ use Symfony\Component\Messenger\Envelope;
118
175
119
176
class ImportantActionToEmailSender implements SenderInterface
120
177
{
@@ -127,10 +184,12 @@ First, create your sender::
127
184
$this->toEmail = $toEmail;
128
185
}
129
186
130
- public function send($message )
187
+ public function send(Envelope $envelope )
131
188
{
189
+ $message = $envelope->getMessage();
190
+
132
191
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));
134
193
}
135
194
136
195
$this->mailer->send(
@@ -165,6 +224,7 @@ First, create your receiver::
165
224
use App\Message\NewOrder;
166
225
use Symfony\Component\Messenger\Transport\ReceiverInterface;
167
226
use Symfony\Component\Serializer\SerializerInterface;
227
+ use Symfony\Component\Messenger\Envelope;
168
228
169
229
class NewOrdersFromCsvFile implements ReceiverInterface
170
230
{
@@ -182,7 +242,9 @@ First, create your receiver::
182
242
$ordersFromCsv = $this->serializer->deserialize(file_get_contents($this->filePath), 'csv');
183
243
184
244
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));
186
248
}
187
249
}
188
250
@@ -196,10 +258,9 @@ Receiver and Sender on the same Bus
196
258
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
197
259
198
260
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.
203
264
204
265
.. _blog posts about command buses : https://matthiasnoback.nl/tags/command%20bus/
205
266
.. _SimpleBus project : http://simplebus.io
0 commit comments