@@ -86,6 +86,65 @@ that will do the required processing for your message::
86
86
}
87
87
}
88
88
89
+ Envelope
90
+ --------
91
+
92
+ The notion of an envelope is a concept that helps add context around the
93
+ messages. An envelope is a message and a set of data. From a user's perspective, this
94
+ allows you to set some configuration around the message. For example, to set the serialization
95
+ groups used when the message goes through the transport layer, wrap your message
96
+ in an ``Envelope `` and add some ``SerializerConfiguration ``::
97
+
98
+ use Symfony\Component\Messenger\Envelope;
99
+ use Symfony\Component\Messenger\Transport\Serialization\SerializerConfiguration;
100
+
101
+ $bus->dispatch(
102
+ (new Envelope($message))->with(new SerializerConfiguration([
103
+ 'groups' => ['my_serialization_groups'],
104
+ ]))
105
+ );
106
+
107
+ At the moment, the Symfony Messenger has the following built-in envelopes:
108
+
109
+ 1. :class: `Symfony\\ Component\\ Messenger\\ Transport\\ Serialization\\ SerializerConfiguration `,
110
+ to configure the serialization groups used by the transport.
111
+ 2. :class: `Symfony\\ Component\\ Messenger\\ Middleware\\ Configuration\\ ValidationConfiguration `,
112
+ to configure the validation groups used when the validation middleware is enabled.
113
+ 3. :class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Transport\\ ReceivedMessage `,
114
+ an internal item that marks the message as received from a transport.
115
+
116
+ Instead of dealing directly with the messages in the middleware you can receive the
117
+ envelope by implementing the :class: `Symfony\\ Component\\ Messenger\\ EnvelopeAwareInterface `
118
+ marker, like this::
119
+
120
+ use Symfony\Component\Messenger\Asynchronous\Transport\ReceivedMessage;
121
+ use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
122
+ use Symfony\Component\Messenger\EnvelopeAwareInterface;
123
+
124
+ class MyOwnMiddleware implements MiddlewareInterface, EnvelopeAwareInterface
125
+ {
126
+ public function handle($message, callable $next)
127
+ {
128
+ // $message here is an `Envelope` object, because this middleware
129
+ // implements the EnvelopeAwareInterface interface. Otherwise,
130
+ // it would be the "original" message.
131
+
132
+ if (null !== $message->get(ReceivedMessage::class)) {
133
+ // Message just has been received...
134
+
135
+ // You could for example add another item.
136
+ $message = $message->with(new AnotherEnvelopeItem(/* ... */));
137
+ }
138
+
139
+ return $next($message);
140
+ }
141
+ }
142
+
143
+ The above example will forward the message to the next middleware with an additional
144
+ envelope item if the message has just been received (i.e. has the `ReceivedMessage ` item).
145
+ You can create your own items by implementing the :class: `Symfony\\ Component\\ Messenger\\ EnvelopeAwareInterface `
146
+ interface.
147
+
89
148
Transports
90
149
----------
91
150
@@ -106,6 +165,7 @@ First, create your sender::
106
165
107
166
use App\Message\ImportantAction;
108
167
use Symfony\Component\Messenger\Transport\SenderInterface;
168
+ use Symfony\Component\Messenger\Envelope;
109
169
110
170
class ImportantActionToEmailSender implements SenderInterface
111
171
{
@@ -118,10 +178,12 @@ First, create your sender::
118
178
$this->toEmail = $toEmail;
119
179
}
120
180
121
- public function send($message )
181
+ public function send(Envelope $envelope )
122
182
{
183
+ $message = $envelope->getMessage();
184
+
123
185
if (!$message instanceof ImportantAction) {
124
- throw new \InvalidArgumentException(sprintf('Producer only supports "%s" messages.', ImportantAction::class));
186
+ throw new \InvalidArgumentException(sprintf('This transport only supports "%s" messages.', ImportantAction::class));
125
187
}
126
188
127
189
$this->mailer->send(
@@ -156,6 +218,7 @@ First, create your receiver::
156
218
use App\Message\NewOrder;
157
219
use Symfony\Component\Messenger\Transport\ReceiverInterface;
158
220
use Symfony\Component\Serializer\SerializerInterface;
221
+ use Symfony\Component\Messenger\Envelope;
159
222
160
223
class NewOrdersFromCsvFile implements ReceiverInterface
161
224
{
@@ -173,7 +236,9 @@ First, create your receiver::
173
236
$ordersFromCsv = $this->serializer->deserialize(file_get_contents($this->filePath), 'csv');
174
237
175
238
foreach ($ordersFromCsv as $orderFromCsv) {
176
- $handler(new NewOrder($orderFromCsv['id'], $orderFromCsv['account_id'], $orderFromCsv['amount']));
239
+ $order = new NewOrder($orderFromCsv['id'], $orderFromCsv['account_id'], $orderFromCsv['amount']);
240
+
241
+ $handler(new Envelope($order));
177
242
}
178
243
}
179
244
@@ -187,7 +252,6 @@ Receiver and Sender on the same Bus
187
252
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
188
253
189
254
To allow sending and receiving messages on the same bus and prevent an infinite
190
- loop, the message bus is equipped with the ``WrapIntoReceivedMessage `` middleware.
191
- It will wrap the received messages into ``ReceivedMessage `` objects and the
192
- ``SendMessageMiddleware `` middleware will know it should not route these
193
- messages again to a transport.
255
+ loop, the message bus will add a :class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Transport\\ ReceivedMessage `
256
+ envelope item to the message envelopes and the :class: `Symfony\\ Component\\ Messenger\\ Asynchronous\\ Middleware\\ SendMessageMiddleware `
257
+ middleware will know it should not route these messages again to a transport.
0 commit comments