The Messenger component provides a message bus with the ability to send messages and handle them synchronously or asynchronously via transport (queues). The main elements of Messenger are messages (a PHP class that holds data), handlers (a PHP class that is called when messages supported by it are dispatched) and transports (which handle the sending and dispatching of messages).
If you have a message class like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/Message/SomeNotification.php
namespace App\Message;
class SomeNotification
{
public function __construct(
private string $content,
) {
}
public function getContent(): string
{
return $this->content;
}
}
Assuming that you also define a SomeNotificationHandler
class in your application,
you can use the following configuration to tell Symfony that the message should be
dispatched to a transport/queue called async
:
1 2 3 4 5 6 7 8
# config/packages/messenger.yaml
framework:
messenger:
transports:
async: "%env(MESSENGER_TRANSPORT_DSN)%"
routing:
'App\Message\SomeNotification': async
In Symfony 7.2, we're introducing a new #[AsMessage]
attribute, allowing you
to configure the transport(s) directly within the message class. In the above example,
you can now remove the routing:
configuration in messenger.yaml
and add
the following to the message class:
1 2 3 4 5
#[AsMessage('async')]
class SomeNotification
{
// ...
}
This attribute allows to pass more than one transport in case you send the message to multiple transports:
1 2
#[AsMessage(['async', 'audit'])]
class SomeNotification
If you define both YAML/XML configuration and a PHP attribute, the configuration always takes precedence over the class attribute. This behavior allows you to override routing on a per-environment basis.
Great, it looks like a logical continuation of #[AsMessageHandler]
Cool, thanks ! 👍🏻
Interesting! In our routing config, interfaces are referenced instead of specific messages. Would this attribute work with interfaces or should we declare it on each implementation?
Great enhancement, thanks! Helps a lot in putting configuration context close to implementation. Not pro or con "framework coupling", but to give other engineers clear hints what these classes are about.
I'd even say; let the Messenger component throw exceptions when these annotated classes are used in wrong contexts (e.g. when being configured as handler / transport).