Installation
composer require draw/messenger-bundle
Add to config/app.php under providers:
Draw\MessengerBundle\MessengerBundle::class,
Publish Config
php artisan vendor:publish --provider="Draw\MessengerBundle\MessengerBundle" --tag="config"
This generates config/messenger.php with default settings (e.g., default_queue, connections, middleware).
First Use Case: Dispatching a Message
Define a message class (e.g., app/Messages/WelcomeUser.php):
namespace App\Messages;
class WelcomeUser
{
public function __construct(public string $userId) {}
}
Dispatch it in a controller or service:
use Draw\MessengerBundle\Messenger\MessageBus;
class UserController extends Controller
{
public function __construct(private MessageBus $bus) {}
public function register()
{
$this->bus->dispatch(new WelcomeUser('user-123'));
}
}
Configure a Queue Connection
Edit config/messenger.php to define a queue (e.g., database or redis):
'connections' => [
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
],
],
Run the Worker
php artisan messenger:work
Or use a process manager (e.g., Supervisor) for production.
Message Dispatching
MessageBus in controllers/services.$this->bus->dispatch(new ProcessOrder($orderId))
->then(new NotifyCustomer($orderId))
->catch(function (OrderFailedException $e) {
$this->bus->dispatch(new LogError($e));
});
Handling Messages
Draw\MessengerBundle\Messenger\MessageHandlerInterface:
class WelcomeUserHandler implements MessageHandlerInterface
{
public function handle(WelcomeUser $message)
{
// Logic to send welcome email
}
}
config/messenger.php:
'handlers' => [
WelcomeUser::class => [
'handler' => App\Handlers\WelcomeUserHandler::class,
'queue' => 'emails',
],
],
Queue Prioritization
'handlers' => [
HighPriorityMessage::class => [
'queue' => 'high',
],
],
php artisan messenger:work --queue=high to process specific queues.Middleware for Cross-Cutting Concerns
config/messenger.php:
'middleware' => [
\Draw\MessengerBundle\Middleware\LogMessage::class,
\App\Middleware\ValidateUser::class,
],
Draw\MessengerBundle\Messenger\Middleware\MiddlewareInterface.Retry Logic
config/messenger.php:
'retry_after' => 60, // seconds
'max_retries' => 3,
Event::listen(OrderPlaced::class, function (OrderPlaced $event) {
$bus->dispatch(new ProcessOrder($event->orderId));
});
MessageBus in tests with mock handlers:
$bus = new MessageBus([new MockHandler()]);
$bus->dispatch(new TestMessage());
Handler Registration
config/messenger.php.App\Handlers\WelcomeUserHandler).php artisan messenger:list to verify registered handlers.Queue Connection Misconfiguration
config/messenger.php and test with:
php artisan messenger:table
(for database queues).Middleware Order Matters
config/messenger.php in the desired execution order.Worker Process Management
[program:messenger]
command=php /path/to/artisan messenger:work --queue=high,low
autostart=true
autorestart=true
Message Serialization
Log Messages: Enable logging in config/messenger.php:
'log' => true,
Check storage/logs/laravel.log for dispatch/handle events.
Inspect Queues: Use Laravel’s queue tools:
php artisan queue:failed # List failed jobs
php artisan queue:flush # Clear all jobs
Handler Debugging: Add temporary logging in handlers:
public function handle(WelcomeUser $message)
{
\Log::info('Handling welcome for', ['userId' => $message->userId]);
// ...
}
Custom Message Bus
Override MessageBus to add features (e.g., deduplication):
class CustomMessageBus extends MessageBus
{
public function dispatch($message)
{
if ($this->isDuplicate($message)) {
return false;
}
return parent::dispatch($message);
}
}
Dynamic Handlers Use service providers to dynamically register handlers:
public function register()
{
$this->app->bind(MessageHandlerInterface::class, function ($app, $params) {
return new DynamicHandler();
});
}
Queue Monitoring Extend the worker to expose metrics (e.g., via HTTP endpoint):
// In a custom worker command
public function handle()
{
$metrics = $this->getMetrics();
file_put_contents('/tmp/messenger_metrics', json_encode($metrics));
}
Message Validation Add validation middleware to reject malformed messages:
class ValidateMessage implements MiddlewareInterface
{
public function handle($message, Closure $next)
{
if (!$this->isValid($message)) {
throw new InvalidMessageException();
}
return $next($message);
}
}
How can I help you explore Laravel packages today?