Installation Add the package via Composer:
composer require bobrd/messagebus-bundle
Register the bundle in config/app.php under providers:
BobrD\MessageBusBundle\MessageBusServiceProvider::class,
Basic Configuration Publish the default config:
php artisan vendor:publish --provider="BobrD\MessageBusBundle\MessageBusServiceProvider" --tag="config"
Edit config/messagebus.php to define your bus (e.g., sync, async, or custom).
First Use Case: Sending a Message
Define a message class (e.g., app/Events/MessageSent.php):
namespace App\Events;
class MessageSent {
public function __construct(public string $content) {}
}
Dispatch it via the bus:
use BobrD\MessageBusBundle\MessageBus;
$bus = app(MessageBus::class);
$bus->dispatch(new MessageSent('Hello, Bus!'));
Handling Messages
Register a handler (e.g., app/Handlers/MessageSentHandler.php):
namespace App\Handlers;
use App\Events\MessageSent;
class MessageSentHandler {
public function __invoke(MessageSent $message) {
// Handle the message
}
}
Bind the handler in a service provider:
$this->app->bind(MessageSent::class, function () {
return new MessageSentHandler();
});
Synchronous Bus
Use the default sync bus for immediate processing:
$bus = app(MessageBus::class)->bus('sync');
$bus->dispatch(new MessageSent('Sync message'));
Asynchronous Bus
Configure an async bus (e.g., with queue driver) in config/messagebus.php:
'buses' => [
'async' => [
'driver' => 'queue',
'queue' => 'messagebus',
],
],
Dispatch messages to the async bus:
$bus->bus('async')->dispatch(new MessageSent('Async message'));
Middleware Integration Attach middleware to buses (e.g., logging or validation):
$bus->bus('sync')->pipe(function ($message, callable $next) {
logger()->info("Processing: " . get_class($message));
return $next($message);
});
Message Prioritization
Use queue priorities (if using queue driver) by extending the message class:
class HighPriorityMessageSent extends MessageSent {
public function getPriority(): int { return 10; }
}
$bus->dispatch(new MessageSent('Event'));
event(new \App\Events\MessageSentEvent('Event'));
$bus = Mockery::mock(MessageBus::class);
$bus->shouldReceive('dispatch')->once();
\BobrD\MessageBusBundle\Contracts\Bus to create custom transport layers (e.g., Kafka, RabbitMQ).Handler Binding
$this->app->bind(MessageSent::class, MessageSentHandler::class);
Async Bus Configuration
config/queue.php and run:
php artisan queue:work
Circular Dependencies
app():
$bus = app(MessageBus::class);
Message Serialization
__serialize()/__unserialize() or use shouldBeSerializable trait.$bus->pipe(function ($message, callable $next) {
logger()->debug("Message: " . json_encode($message));
return $next($message);
});
php artisan queue:failed-table
php artisan queue:work --once --sleep=3 --tries=1
Custom Bus Drivers
Implement \BobrD\MessageBusBundle\Contracts\Bus to add support for new transports (e.g., gRPC, WebSockets).
Message Metadata
Attach metadata to messages via a Metadata interface:
interface Metadata {
public function getHeaders(): array;
}
Access headers in handlers:
$message->getHeaders()['custom_key'] ?? null;
Retry Logic Extend the async bus to support retries:
'async' => [
'driver' => 'queue',
'tries' => 3,
],
Message Validation Use Laravel Validation middleware:
$bus->pipe(function ($message, callable $next) {
$validator = Validator::make($message, ['content' => 'required']);
if ($validator->fails()) {
throw new \InvalidArgumentException($validator->errors()->first());
}
return $next($message);
});
How can I help you explore Laravel packages today?