Messenger (quick look)
Emails, image resizing, webhooks - work you don't want inside the HTTP request. Symfony Messenger is the queue abstraction (sync by default, transports when you grow up).
Mental model
- Create a message class (DTO of intent)
- Create a handler (
__invoke(Message $message)) $bus->dispatch($message)from a controller/command- Transport:
sync(dev), Doctrine, Redis, AMQP…
php
<?php
// Message
final class SendWelcomeEmail
{
public function __construct(public readonly string $userEmail) {}
}
// Handler
final class SendWelcomeEmailHandler
{
public function __construct(private MailerInterface $mailer) {}
public function __invoke(SendWelcomeEmail $message): void
{
// send mail…
}
}php
<?php
$bus->dispatch(new SendWelcomeEmail($user->getEmail()));Comments for the code above:
- Handler is auto-registered when it type-hints the message
- Locally,
MESSENGER_TRANSPORT_DSN=sync://runs handlers inline - easy debugging - Prod: real transport +
messenger:consumeworker process
Consume workers
bash
php bin/console messenger:consume async -vvDeploy means "run HTTP and consumers" - same ops lesson as Laravel queues / Horizon.
When to bother
| Keep in request | Dispatch to Messenger |
|---|---|
| Validate + save post | Resize upload |
| Return JSON | Call slow third-party API |
| Tiny email in free-time toy apps | Bulk mail / digests |
As you can see, it's the same "don't block the response" instinct you have with background jobs on the FE… except the failure modes are on your servers 😅
Next: where to go after this tutorial.
Best,
-- ł.