8000 feature #9727 [Messenger] Update the messenger documentation (sroze) · symfony/symfony-docs@2099d48 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2099d48

Browse 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

File tree

2 files changed

+165
-42
lines changed

2 files changed

+165
-42
lines changed

components/messenger.rst

Lines 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

Lines 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 responsib F438 le 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 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: ~
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