Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2099d48

Browse filesBrowse files
committed
feature #9727 [Messenger] Update the messenger documentation (sroze)
This PR was submitted for the master branch but it was squashed and merged into the 4.1 branch instead (closes #9727). Discussion ---------- [Messenger] Update the messenger documentation - [x] Fixes #9641 with the middleware configuration. - [x] Fixes #9617 with the multiple bus configuration. - [x] Change adapters to transports (waiting merge: symfony/symfony#27129) - [x] middlewares config entry is renamed middleware (symfony/symfony#27177) - [x] in the config, message buses names are the full service id you'll use (symfony/symfony#27162) - [x] Add TransportInterface as first class citizen sender+receiver (symfony/symfony#27164) Commits ------- c3c3528 Few updates following review 64bfd75 Change wording and don't use `.`-based services so it's just clearer e1f3b5a Fix the formating of the method name 9b7b85f Update the example of using multiple buses to use DI's `bind`s c76b2c2 Uses the full service name when configuring the buses from the YAML configuration 2409798 Middleware does not have a plural a20286d Add a note about the symfony serializer pack 10f46eb Introduce the `TransportInterface` ef70bc0 Add a documentation about the middlewares 3ff8cfe Add multiple buses configuration and type-hint example a4bc592 Rename the adapters to transport
2 parents cc6768e + c3c3528 commit 2099d48
Copy full SHA for 2099d48

File tree

2 files changed

+165
-42
lines changed
Filter options

2 files changed

+165
-42
lines changed

‎components/messenger.rst

Copy file name to clipboardExpand all lines: components/messenger.rst
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ that will do the required processing for your message::
8686
}
8787
}
8888

89-
Adapters
90-
--------
89+
Transports
90+
----------
9191

92-
In order to send and receive messages, you will have to configure an adapter. An
93-
adapter will be responsible of communicating with your message broker or 3rd parties.
92+
In order to send and receive messages, you will have to configure a transport. An
93+
transport will be responsible of communicating with your message broker or 3rd parties.
9494

9595
Your own sender
9696
~~~~~~~~~~~~~~~
@@ -190,4 +190,4 @@ To allow us to receive and send messages on the same bus and prevent an infinite
190190
loop, the message bus is equipped with the ``WrapIntoReceivedMessage`` middleware.
191191
It will wrap the received messages into ``ReceivedMessage`` objects and the
192192
``SendMessageMiddleware`` middleware will know it should not route these
193-
messages again to an adapter.
193+
messages again to a transport.

‎messenger.rst

Copy file name to clipboardExpand all lines: messenger.rst
+160-37Lines changed: 160 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ How to Use the Messenger
55
========================
66

77
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.
99
Before using it, read the :doc:`Messenger component docs </components/messenger>`
1010
to get familiar with its concepts.
1111

@@ -44,7 +44,7 @@ Registering Handlers
4444
--------------------
4545

4646
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::
4848

4949
// src/MessageHandler/MyMessageHandler.php
5050
namespace App\MessageHandler;
@@ -70,19 +70,19 @@ Once you've created your handler, you need to register it:
7070
If the message cannot be guessed from the handler's type-hint, use the
7171
``handles`` attribute on the tag.
7272

73-
Adapters
74-
--------
73+
Transports
74+
----------
7575

7676
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
7878
most of the AMQP brokers such as RabbitMQ.
7979

8080
.. note::
8181

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`_
8383
which supports things like Kafka, Amazon SQS or Google Pub/Sub.
8484

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
8686
connection credentials and configuration. By default, when you've installed
8787
the messenger component, the following configuration should have been created:
8888

@@ -91,7 +91,7 @@ the messenger component, the following configuration should have been created:
9191
# config/packages/messenger.yaml
9292
framework:
9393
messenger:
94-
adapters:
94+
transports:
9595
amqp: "%env(MESSENGER_DSN)%"
9696
9797
.. code-block:: bash
@@ -107,11 +107,20 @@ configure the following services for you:
107107
1. A ``messenger.sender.amqp`` sender to be used when routing messages.
108108
2. A ``messenger.receiver.amqp`` receiver to be used when consuming messages.
109109

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+
110119
Routing
111120
-------
112121

113122
Instead of calling a handler, you have the option to route your message(s) to a
114-
sender. Part of an adapter, it is responsible for sending your message somewhere.
123+
sender. Part of a transport, it is responsible for sending your message somewhere.
115124
You can configure which message is routed to which sender with the following
116125
configuration:
117126

@@ -120,7 +129,7 @@ configuration:
120129
framework:
121130
messenger:
122131
routing:
123-
'My\Message\Message': amqp # The name of the defined adapter
132+
'My\Message\Message': amqp # The name of the defined transport
124133
125134
Such configuration would only route the ``My\Message\Message`` message to be
126135
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
132141
framework:
133142
messenger:
134143
routing:
135-
'My\Message\MessageAboutDoingOperationalWork': another_adapter
144+
'My\Message\MessageAboutDoingOperationalWork': another_transport
136145
'*': amqp
137146
138147
A class of message can also be routed to multiple senders by specifying a list:
@@ -166,39 +175,153 @@ like this:
166175
$ bin/console messenger:consume-messages amqp
167176
168177
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 buses (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: ~
170200
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.
173203

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+
~~~~~~~~~~~~~~~~~~~~~~~~~~
176206

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.
179210

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
182250
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;
184290
use Symfony\Component\Messenger\Transport\ReceiverInterface;
185291
use Symfony\Component\Messenger\Transport\SenderInterface;
186292

187-
class YourAdapterFactory implements AdapterFactoryInterface
293+
class YourTransportFactory implements TransportFactoryInterface
188294
{
189-
public function createReceiver(string $dsn, array $options): ReceiverInterface
295+
public function createTransport(string $dsn, array $options): TransportInterface
190296
{
191-
return new YourReceiver(/* ... */);
297+
return new YourTransport(/* ... */);
192298
}
193299

194-
public function createSender(string $dsn, array $options): SenderInterface
300+
public function supports(string $dsn, array $options): bool
195301
{
196-
return new YourSender(/* ... */);
302+
return 0 === strpos($dsn, 'my-transport://');
197303
}
304+
}
198305

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
200323
{
201-
return 0 === strpos($dsn, 'my-adapter://');
324+
// ...
202325
}
203326
}
204327

@@ -207,27 +330,27 @@ Register your factory
207330

208331
.. code-block:: xml
209332
210-
<service id="Your\Adapter\YourAdapterFactory">
211-
<tag name="messenger.adapter_factory" />
333+
<service id="Your\Transport\YourTransportFactory">
334+
<tag name="messenger.transport_factory" />
212335
</service>
213336
214-
Use your adapter
215-
~~~~~~~~~~~~~~~~
337+
Use your transport
338+
~~~~~~~~~~~~~~~~~~
216339

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:
219342

220343
.. code-block:: yaml
221344
222345
framework:
223346
messenger:
224-
adapters:
225-
yours: 'my-adapter://...'
347+
transports:
348+
yours: 'my-transport://...'
226349
227350
In addition of being able to route your messages to the ``yours`` sender, this
228351
will give you access to the following services:
229352

230353
#. ``messenger.sender.yours``: the sender.
231354
#. ``messenger.receiver.yours``: the receiver.
232355

233-
.. _`enqueue's adapter`: https://github.com/sroze/enqueue-bridge
356+
.. _`enqueue's transport`: https://github.com/enqueue/messenger-adapter

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.