11.. index ::
2- single: Message
3- single: Components; Message
2+ single: Messenger
3+ single: Components; Messenger
44
5- The Message Component
6- =====================
5+ The Messenger Component
6+ =======================
77
8- The Message component helps application to send and receive messages
9- to/from other applications or via
8+ The Messenger component helps application send and receive messages to/from other applications or via message queues.
109
1110Installation
1211------------
1312
1413.. code-block :: terminal
1514
16- $ composer require symfony/message
15+ $ composer require symfony/messenger
1716
18- Alternatively, you can clone the `<https://github.com/symfony/message >`_ repository.
17+ Alternatively, you can clone the `<https://github.com/symfony/messenger >`_ repository.
1918
2019.. include :: /components/require_autoload.rst.inc
2120
2221Concepts
2322--------
2423
25- .. image :: /_images/components/message /overview.png
24+ .. image :: /_images/components/messenger /overview.png
2625
2726**Sender **:
2827 Responsible for serializing and sending the message to _something_. This
@@ -47,19 +46,28 @@ following middlewares are configured for you:
4746#. ``SendMessageMiddleware `` (enables asynchronous processing)
4847#. ``HandleMessageMiddleware `` (calls the registered handle)
4948
50- Example::
49+ Example:
5150
5251 use App\M essage\M yMessage;
52+ use Symfony\C omponent\M essenger\M essageBus;
53+ use Symfony\C omponent\M essenger\H andlerLocator;
54+ use Symfony\C omponent\M essenger\M iddleware\H andleMessageMiddleware;
5355
54- $result = $this->get('message_bus')->handle(new MyMessage(/* ... */));
56+ $bus = new MessageBus([
57+ new HandleMessageMiddleware(new HandlerLocator([
58+ MyMessage::class => $handler,
59+ ]))
60+ ]);
61+
62+ $result = $bus->handle(new MyMessage(/* ... */));
5563
5664Handlers
5765--------
5866
5967Once dispatched to the bus, messages will be handled by a "message handler". A
6068message handler is a PHP callable (i.e. a function or an instance of a class)
6169that will do the required processing for your message. It _might_ return a
62- result::
70+ result:
6371
6472 namespace App\M essageHandler;
6573
@@ -73,80 +81,14 @@ result::
7381 }
7482 }
7583
76- .. code-block :: xml
77-
78- <service id =" App\Handler\MyMessageHandler" >
79- <tag name =" message_handler" />
80- </service >
81-
82- .. note ::
83-
84- If the message cannot be guessed from the handler's type-hint, use the
85- ``handles `` attribute on the tag.
86-
87- Asynchronous messages
88- ~~~~~~~~~~~~~~~~~~~~~
89-
90- Using the Message Component is useful to decouple your application but it also
91- very useful when you want to do some asynchronous processing. This means that
92- your application will produce a message to a queuing system and consume this
93- message later in the background, using a _worker_.
94-
9584Adapters
96- ~~~~~~~~
85+ --------
9786
9887The communication with queuing system or third parties is delegated to
99- libraries for now. You can use one of the following adapters:
100-
101- #. `PHP Enqueue bridge `_ to use one of their 10+ compatible queues such as
102- RabbitMq, Amazon SQS or Google Pub/Sub.
103-
104- Routing
105- -------
106-
107- When doing asynchronous processing, the key is to route the message to the right
108- sender. As the routing is application-specific and not message-specific, the
109- configuration can be made within the ``framework.yaml `` configuration file as
110- well:
111-
112- .. code-block :: yaml
113-
114- framework :
115- message :
116- routing :
117- ' My\Message\MessageAboutDoingOperationalWork ' : my_operations_queue_sender
88+ libraries for now.
11889
119- Such configuration would only route the ``MessageAboutDoingOperationalWork ``
120- message to be asynchronous, the rest of the messages would still be directly
121- handled.
122-
123- If you want to do route all the messages to a queue by default, you can use such
124- configuration:
125-
126- .. code-block :: yaml
127-
128- framework :
129- message :
130- routing :
131- ' My\Message\MessageAboutDoingOperationalWork ' : my_operations_queue_sender
132- ' * ' : my_default_sender
133-
134- Note that you can also route a message to multiple senders at the same time:
135-
136- .. code-block :: yaml
137-
138- framework :
139- message :
140- routing :
141- ' My\Message\AnImportantMessage ' : [my_default_sender, my_audit_sender]
142-
143- Same bus received and sender
144- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
145-
146- To allow us to receive and send messages on the same bus and prevent a loop, the
147- message bus is equipped with the ``WrapIntoReceivedMessage `` received. It will
148- wrap the received messages into ``ReceivedMessage `` objects and the
149- ``SendMessageMiddleware `` middleware will know it should not send these messages.
90+ Create your adapter
91+ ~~~~~~~~~~~~~~~~~~~
15092
15193Your own sender
15294---------------
@@ -160,8 +102,8 @@ First, create your sender::
160102
161103 namespace App\MessageSender;
162104
163- use Symfony\Component\Message\SenderInterface;
164105 use App\Message\ImportantAction;
106+ use Symfony\Component\Message\SenderInterface;
165107
166108 class ImportantActionToEmailSender implements SenderInterface
167109 {
@@ -191,33 +133,6 @@ First, create your sender::
191133 }
192134 }
193135
194- Then, register your sender service:
195-
196- .. code-block :: yaml
197-
198- services :
199- App\MessageSender\ImportantActionToEmailSender :
200- arguments :
201- - " @mailer"
202- - " %to_email%"
203-
204- tags :
205- - message.sender
206-
207- Finally, route your important message to the sender:
208-
209- .. code-block :: yaml
210-
211- framework :
212- message :
213- routing :
214- ' App\Message\ImportantAction ' : [App\MessageSender\ImportantActionToEmailSender, ~]
215-
216- .. note ::
217-
218- This example shows you how you can at the same time send your message and
219- directly handle it using a ``null `` (``~ ``) sender.
220-
221136Your own receiver
222137-----------------
223138
@@ -236,11 +151,10 @@ First, create your receiver::
236151
237152 namespace App\MessageReceiver;
238153
154+ use App\Message\NewOrder;
239155 use Symfony\Component\Message\ReceiverInterface;
240156 use Symfony\Component\Serializer\SerializerInterface;
241157
242- use App\Message\NewOrder;
243-
244158 class NewOrdersFromCsvFile implements ReceiverInterface
245159 {
246160 private $serializer;
@@ -262,23 +176,17 @@ First, create your receiver::
262176 }
263177 }
264178
265- Then, register your receiver service:
266-
267- .. code-block :: yaml
179+ Your adapter factory
180+ ~~~~~~~~~~~~~~~~~~~~
268181
269- services :
270- App\MessageReceiver\NewOrdersFromCsvFile :
271- arguments :
272- - " @serializer"
273- - " %new_orders_csv_file_path%"
182+ TODO.
274183
275- tags :
276- - message.receiver
277-
278- Finally, use your consumer:
279-
280- .. code-block :: terminal
184+ Same bus received and sender
185+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
281186
282- $ bin/console message:consume App\MessageReceived\NewOrdersFromCsvFile
187+ To allow us to receive and send messages on the same bus and prevent a loop, the
188+ message bus is equipped with the ``WrapIntoReceivedMessage `` received. It will
189+ wrap the received messages into ``ReceivedMessage `` objects and the
190+ ``SendMessageMiddleware `` middleware will know it should not send these messages.
283191
284192.. _`PHP Enqueue bridge` : https://github.com/sroze/enqueue-bridge
0 commit comments