@@ -5,7 +5,7 @@ How to Use the Messenger
5
5
========================
6
6
7
7
Symfony's Messenger provide a message bus and some routing capabilities to send
8
- messages within your application and through adapters such as message queues.
8
+ messages within your application and through transports such as message queues.
9
9
Before using it, read the :doc: `Messenger component docs </components/messenger >`
10
10
to get familiar with its concepts.
11
11
@@ -44,7 +44,7 @@ Registering Handlers
44
44
--------------------
45
45
46
46
In order to do something when your message is dispatched, you need to create a
47
- message handler. It's a class with an `__invoke ` method::
47
+ message handler. It's a class with an `` __invoke ` ` method::
48
48
49
49
// src/MessageHandler/MyMessageHandler.php
50
50
namespace App\MessageHandler;
@@ -70,19 +70,19 @@ Once you've created your handler, you need to register it:
70
70
If the message cannot be guessed from the handler's type-hint, use the
71
71
``handles `` attribute on the tag.
72
72
73
- Adapters
74
- --------
73
+ Transports
74
+ ----------
75
75
76
76
The communication with queuing system or third parties is delegated to
77
- libraries for now. The built-in AMQP adapter allows you to communicate with
77
+ libraries for now. The built-in AMQP transport allows you to communicate with
78
78
most of the AMQP brokers such as RabbitMQ.
79
79
80
80
.. note ::
81
81
82
- If you need more message brokers, you should have a look to `Enqueue's adapter `_
82
+ If you need more message brokers, you should have a look to `Enqueue's transport `_
83
83
which supports things like Kafka, Amazon SQS or Google Pub/Sub.
84
84
85
- An adapter is registered using a "DSN", which is a string that represents the
85
+ A transport is registered using a "DSN", which is a string that represents the
86
86
connection credentials and configuration. By default, when you've installed
87
87
the messenger component, the following configuration should have been created:
88
88
@@ -91,7 +91,7 @@ the messenger component, the following configuration should have been created:
91
91
# config/packages/messenger.yaml
92
92
framework :
93
93
messenger :
94
- adapters :
94
+ transports :
95
95
amqp : " %env(MESSENGER_DSN)%"
96
96
97
97
.. code-block :: bash
@@ -107,11 +107,20 @@ configure the following services for you:
107
107
1. A ``messenger.sender.amqp `` sender to be used when routing messages.
108
108
2. A ``messenger.receiver.amqp `` receiver to be used when consuming messages.
109
109
110
+ .. note ::
111
+
112
+ In order to use Symfony's built-in AMQP transport, you will need the Serializer
113
+ Component. Ensure that it is installed with:
114
+
115
+ .. code-block :: terminal
116
+
117
+ $ composer require symfony/serializer-pack
118
+
110
119
Routing
111
120
-------
112
121
113
122
Instead of calling a handler, you have the option to route your message(s) to a
114
- sender. Part of an adapter , it is responsib
F438
le for sending your message somewhere.
123
+ sender. Part of a transport , it is responsible for sending your message somewhere.
115
124
You can configure which message is routed to which sender with the following
116
125
configuration:
117
126
@@ -120,7 +129,7 @@ configuration:
120
129
framework :
121
130
messenger :
122
131
routing :
123
- ' My\Message\Message ' : amqp # The name of the defined adapter
132
+ ' My\Message\Message ' : amqp # The name of the defined transport
124
133
125
134
Such configuration would only route the ``My\Message\Message `` message to be
126
135
asynchronous, the rest of the messages would still be directly handled.
@@ -132,7 +141,7 @@ You can route all classes of message to a sender using an asterisk instead of a
132
141
framework :
133
142
messenger :
134
143
routing :
135
- ' My\Message\MessageAboutDoingOperationalWork ' : another_adapter
144
+ ' My\Message\MessageAboutDoingOperationalWork ' : another_transport
136
145
' * ' : amqp
137
146
138
147
A class of message can also be routed to multiple senders by specifying a list:
@@ -166,39 +175,153 @@ like this:
166
175
$ bin/console messenger:consume-messages amqp
167
176
168
177
The first argument is the receiver's service name. It might have been created by
169
- your ``adapters `` configuration or it can be your own receiver.
178
+ your ``transports `` configuration or it can be your own receiver.
179
+
180
+ Multiple buses
181
+ --------------
182
+
183
+ If you are interested into architectures like CQRS, you might want to have multiple
184
+ buses within your application.
185
+
186
+ You can create multiple buse
10000
s (in this example, a command and an event bus) like
187
+ this:
188
+
189
+ .. code-block :: yaml
190
+
191
+ framework :
192
+ messenger :
193
+ # The bus that is going to be injected when injecting MessageBusInterface:
194
+ default_bus : commands
195
+
196
+ # Create buses
197
+ buses :
198
+ messenger.bus.commands : ~
199
+ messenger.bus.events : ~
170
200
171
- Your own Adapters
172
- -----------------
201
+ This will generate the `` messenger.bus.commands `` and `` messenger.bus.events `` services
202
+ that you can inject in your services.
173
203
174
- Once you have written your adapter's sender and receiver, you can register your
175
- adapter factory to be able to use it via a DSN in the Symfony application.
204
+ Type-hints and auto-wiring
205
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
176
206
177
- Create your adapter Factory
178
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
207
+ Auto-wiring is a great feature that allows you to reduce the amount of configuration
208
+ required for your service container to be created. When using multiple buses, by default,
209
+ the auto-wiring will not work as it won't know why bus to inject in your own services.
179
210
180
- You need to give FrameworkBundle the opportunity to create your adapter from a
181
- DSN. You will need an adapter factory::
211
+ In order to clarify this, you can use the DependencyInjection's binding capabilities
212
+ to clarify which bus will be injected based on the argument's name:
213
+
214
+ .. code-block :: yaml
215
+
216
+ # config/services.yaml
217
+ services :
218
+ _defaults :
219
+ # ...
220
+
221
+ bind :
222
+ $commandBus : ' @messenger.bus.commands'
223
+ $eventBus : ' @messenger.bus.events'
224
+
225
+ Middleware
226
+ ----------
227
+
228
+ What happens when you dispatch a message to a message bus(es) depends on its
229
+ collection of middleware (and their order). By default, the middleware configured
230
+ for each bus looks like this:
231
+
232
+ 1. ``logging `` middleware. Responsible of logging the beginning and the end of the
233
+ message within the bus.
234
+
235
+ 2. _Your own collection of middleware _
236
+
237
+ 3. ``route_messages `` middleware. Will route the messages your configured to their
238
+ corresponding sender and stop the middleware chain.
239
+
240
+ 4. ``call_message_handler `` middleware. Will call the message handler(s) for the
241
+ given message.
242
+
243
+ Adding your own middleware
244
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
245
+
246
+ As described in the component documentation, you can add your own middleware
247
+ within the buses to add some extra capabilities like this:
248
+
249
+ .. code-block :: yaml
182
250
183
- use Symfony\Component\Messenger\Adapter\Factory\AdapterFactoryInterface;
251
+ framework :
252
+ messenger :
253
+ buses :
254
+ messenger.bus.default :
255
+ middleware :
256
+ - ' App\Middleware\MyMiddleware'
257
+ - ' App\Middleware\AnotherMiddleware'
258
+
259
+ Note that if the service is abstract, then a different instance of service will be
260
+ created per bus.
261
+
262
+ Disabling default middleware
263
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
264
+
265
+ If you don't want the default collection of middleware to be present on your bus,
266
+ you can disable them like this:
267
+
268
+ .. code-block :: yaml
269
+
270
+ framework :
271
+ messenger :
272
+ buses :
273
+ messenger.bus.default :
274
+ default_middleware : false
275
+
276
+ Your own Transport
277
+ ------------------
278
+
279
+ Once you have written your transport's sender and receiver, you can register your
280
+ transport factory to be able to use it via a DSN in the Symfony application.
281
+
282
+ Create your Transport Factory
283
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
284
+
285
+ You need to give FrameworkBundle the opportunity to create your transport from a
286
+ DSN. You will need an transport factory::
287
+
288
+ use Symfony\Component\Messenger\Transport\TransportFactoryInterface;
289
+ use Symfony\Component\Messenger\Transport\TransportInterface;
184
290
use Symfony\Component\Messenger\Transport\ReceiverInterface;
185
291
use Symfony\Component\Messenger\Transport\SenderInterface;
186
292
187
- class YourAdapterFactory implements AdapterFactoryInterface
293
+ class YourTransportFactory implements TransportFactoryInterface
188
294
{
189
- public function createReceiver (string $dsn, array $options): ReceiverInterface
295
+ public function createTransport (string $dsn, array $options): TransportInterface
190
296
{
191
- return new YourReceiver (/* ... */);
297
+ return new YourTransport (/* ... */);
192
298
}
193
299
194
- public function createSender (string $dsn, array $options): SenderInterface
300
+ public function supports (string $dsn, array $options): bool
195
301
{
196
- return new YourSender(/* ... */ );
302
+ return 0 === strpos($dsn, 'my-transport://' );
197
303
}
304
+ }
198
305
199
- public function supports(string $dsn, array $options): bool
306
+ The transport object is needs to implements the ``TransportInterface `` (which simply combine
307
+ the ``SenderInterface `` and ``ReceiverInterface ``). It will look
308
+ like this::
309
+
310
+ class YourTransport implements TransportInterface
311
+ {
312
+ public function send($message) : void
313
+ {
314
+ // ...
315
+ }
316
+
317
+ public function receive(callable $handler) : void
318
+ {
319
+ // ...
320
+ }
321
+
322
+ public function stop() : void
200
323
{
201
- return 0 === strpos($dsn, 'my-adapter://');
324
+ // ...
202
325
}
203
326
}
204
327
@@ -207,27 +330,27 @@ Register your factory
207
330
208
331
.. code-block :: xml
209
332
210
- <service id =" Your\Adapter\YourAdapterFactory " >
211
- <tag name =" messenger.adapter_factory " />
333
+ <service id =" Your\Transport\YourTransportFactory " >
334
+ <tag name =" messenger.transport_factory " />
212
335
</service >
213
336
214
- Use your adapter
215
- ~~~~~~~~~~~~~~~~
337
+ Use your transport
338
+ ~~~~~~~~~~~~~~~~~~
216
339
217
- Within the ``framework.messenger.adapters .* `` configuration, create your
218
- named adapter using your own DSN:
340
+ Within the ``framework.messenger.transports .* `` configuration, create your
341
+ named transport using your own DSN:
219
342
220
343
.. code-block :: yaml
221
344
222
345
framework :
223
346
messenger :
224
- adapters :
225
- yours : ' my-adapter ://...'
347
+ transports :
348
+ yours : ' my-transport ://...'
226
349
227
350
In addition of being able to route your messages to the ``yours `` sender, this
228
351
will give you access to the following services:
229
352
230
353
#. ``messenger.sender.yours ``: the sender.
231
354
#. ``messenger.receiver.yours ``: the receiver.
232
355
233
- .. _`enqueue's adapter ` : https://github.com/sroze/ enqueue-bridge
356
+ .. _`enqueue's transport ` : https://github.com/enqueue/messenger-adapter
0 commit comments