event-engine/php-messaging
Messaging components for PHP apps: message bus, commands, events and queries with middleware-style dispatching. Designed to pair with Event Engine/event sourcing stacks but usable standalone for structured, testable message handling.
Installation
composer require event-engine/php-messaging
Add the service provider to config/app.php:
'providers' => [
// ...
EventEngine\Messaging\MessagingServiceProvider::class,
],
Publish Config
php artisan vendor:publish --provider="EventEngine\Messaging\MessagingServiceProvider"
Configure config/messaging.php with your broker (e.g., RabbitMQ, Redis, or SQS).
First Use Case: Sending a Message
use EventEngine\Messaging\Message;
// Define a message
$message = new Message('user.created', [
'user_id' => 123,
'email' => 'user@example.com'
]);
// Send via the facade (or container)
\Messaging::send($message);
Consuming Messages Create a listener class:
namespace App\Listeners;
use EventEngine\Messaging\Message;
use EventEngine\Messaging\Contracts\MessageListener;
class HandleUserCreated implements MessageListener
{
public function handle(Message $message)
{
// Process the message
logger()->info('User created:', $message->payload());
}
}
Register it in config/messaging.php under listeners.
Message Dispatching
\Messaging::send() for simplicity.use EventEngine\Messaging\Jobs\SendMessage;
SendMessage::dispatch($message);
\Messaging::sendBatch([
new Message('order.processed', ['order_id' => 1]),
new Message('notification.send', ['user_id' => 1]),
]);
Listener Registration
$this->app->bind(MessageListener::class, function ($app) {
return new HandleUserCreated();
});
priority key in config/messaging.php to order listeners.Message Serialization
config/messaging.php:
'serializer' => \Symfony\Component\Serializer\Serializer::class,
EventEngine\Messaging\Contracts\MessageSerializer.Error Handling
config/messaging.php:
'retry' => [
'max_attempts' => 3,
'delay' => 1000, // ms
],
'dead_letter' => [
'enabled' => true,
'queue' => 'dead-letters',
],
Integration with Laravel Events
public function handle(UserCreated $event)
{
\Messaging::send(new Message('user.created', $event->toArray()));
}
Broker Connection Issues
config/messaging.php and check broker health (e.g., rabbitmqctl status for RabbitMQ).'log' => [
'enabled' => true,
'channel' => 'single',
],
Listener Not Triggered
config/messaging.php or incorrect message topic.topic method to explicitly bind listeners:
\Messaging::listen('user.created', HandleUserCreated::class);
Serialization Errors
Message payload must be JSON serializable.JsonSerializable:
$message = new Message('event.name', json_serializable_object());
Race Conditions
if ($message->id() && $this->alreadyProcessed($message->id())) {
return;
}
Performance Bottlenecks
\Messaging::sendBatch(array_map(fn ($user) => new Message('user.updated', ['id' => $user->id]), $users));
Custom Broker Adapters
EventEngine\Messaging\Contracts\Broker to support unsupported brokers (e.g., Kafka):
class KafkaBroker implements Broker
{
public function publish(Message $message) { /* ... */ }
public function consume(callable $callback) { /* ... */ }
}
Message Middleware
\Messaging::extend('kafka', function ($app) {
return new KafkaBroker($app['kafka']);
});
Testing
$this->app->instance(Broker::class, new MockBroker());
MessagingTestCase trait for assertions:
use EventEngine\Messaging\Testing\MessagingTestCase;
class MyTest extends MessagingTestCase
{
public function testMessageSent()
{
$this->assertSent('user.created');
}
}
Configuration Quirks
'broker' => env('MESSAGING_BROKER', 'redis'),
config/messaging.php:
'defaults' => [
'exchange' => 'default_exchange',
'queue' => 'default_queue',
],
Monitoring
\Messaging::middleware(function ($message, $next) {
logger()->info('Message sent:', ['topic' => $message->topic(), 'payload' => $message->payload()]);
return $next($message);
});
How can I help you explore Laravel packages today?