@@ -89,6 +89,65 @@ that will do the required processing for your message::
89
89
}
90
90
}
91
91
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
+
92
151
Transports
93
152
----------
94
153
@@ -109,6 +168,7 @@ First, create your sender::
109
168
110
169
use App\Message\ImportantAction;
111
170
use Symfony\Component\Messenger\Transport\SenderInterface;
171
+ use Symfony\Component\Messenger\Envelope;
112
172
113
173
class ImportantActionToEmailSender implements SenderInterface
114
174
{
@@ -121,10 +181,12 @@ First, create your sender::
121
181
$this->toEmail = $toEmail;
122
182
}
123
183
124
- public function send($message )
184
+ public function send(Envelope $envelope )
125
185
{
186
+ $message = $envelope->getMessage();
187
+
126
188
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));
128
190
}
129
191
130
192
$this->mailer->send(
@@ -159,6 +221,7 @@ First, create your receiver::
159
221
use App\Message\NewOrder;
160
222
use Symfony\Component\Messenger\Transport\ReceiverInterface;
161
223
use Symfony\Component\Serializer\SerializerInterface;
224
+ use Symfony\Component\Messenger\Envelope;
162
225
163
226
class NewOrdersFromCsvFile implements ReceiverInterface
164
227
{
@@ -176,7 +239,9 @@ First, create your receiver::
176
239
$ordersFromCsv = $this->serializer->deserialize(file_get_contents($this->filePath), 'csv');
177
240
178
241
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));
180
245
}
181
246
}
182
247
@@ -190,11 +255,9 @@ Receiver and Sender on the same Bus
190
255
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191
256
192
257
To 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.
198
261
199
262
.. _blog posts about command buses : https://matthiasnoback.nl/tags/command%20bus/
200
263
.. _SimpleBus project : http://simplebus.io
0 commit comments