Pierre Rineau
Contributed by Pierre Rineau in #57507

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.

Published in #Living on the edge