@@ -5,7 +5,7 @@ How to Use the Messenger
55========================
66
77Symfony'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.
99Before using it, read the :doc: `Messenger component docs </components/messenger >`
1010to get familiar with its concepts.
1111
@@ -44,7 +44,7 @@ Registering Handlers
4444--------------------
4545
4646In 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
7676The 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
7878most 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
8686connection credentials and configuration. By default, when you've installed
8787the 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:
1071071. A ``messenger.sender.amqp `` sender to be used when routing messages.
1081082. 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
113122Instead 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.
115124You can configure which message is routed to which sender with the following
116125configuration:
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
126135asynchronous, 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
228351will 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