nuwber / rabbitevents
The Nuwber RabbitEvents package
Fund package maintenance!
masterjus
Installs: 506 332
Dependents: 3
Suggesters: 1
Security: 0
Stars: 121
Watchers: 9
Forks: 34
Open Issues: 0
pkg:composer/nuwber/rabbitevents
Requires
- php: ^8.1
- ext-json: *
- enqueue/amqp-lib: ^0.10
- illuminate/console: 9 - 12
- illuminate/container: 9 - 12
- illuminate/events: 9 - 12
- illuminate/support: 9 - 12
Requires (Dev)
- mockery/mockery: ^1.6.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.5|^11.0
- vlucas/phpdotenv: ^v5.6
Suggests
- ext-amqp: Using this extension makes your app faster. If you're using it you need to install enqueue/amqp-ext.
- ext-pcntl: Required to use all features of the worker.
- enqueue/amqp-ext: This package is necessary if you want to use `ext-amqp`.
Replaces
- rabbitevents/foundation: v8.2.3
- rabbitevents/listener: v8.2.3
- rabbitevents/publisher: v8.2.3
- 9.x-dev
- 8.x-dev
- v8.2.3
- v8.2.2
- v8.2.1
- v8.2.0
- v8.1.5
- v8.1.4
- v8.1.3
- v8.1.2
- v8.1.1
- v8.1.0
- v8.1.0-beta.1
- v8.0.1
- v8.0.0
- 7.x-dev
- v7.3.0
- v7.2.0
- v7.1.1
- v7.1.0
- v7.0.1
- v7.0
- v7.0-rc.1
- v7.0-beta.4
- v7.0-beta.3
- v7.0-beta.2
- v7.0-beta.1
- 6.x-dev
- v6.1.0
- v6.0.6
- v6.0.5
- v6.0.4
- v6.0.3
- v6.0.2
- v6.0.1
- v6.0
- v6.0.0-RC2
- v6.0.0-RC1
- v5.7
- v5.6
- v5.5
- v5.4
- v5.3
- v5.2
- v5.1
- v5.0
- v5.0-beta.1
- v4.3
- v4.2
- v4.1
- v4.0
- v4.0-beta.2
- 4.0-beta.1
- v3.1
- v3.0
- v3.0-beta2
- v3.0-beta1
- v2.0
- v1.4
- v1.3
- v1.2
- v1.1
- v1.0
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- dev-new-features
- dev-l12-bump
- dev-master
This package is auto-updated.
Last update: 2026-02-03 10:17:25 UTC
README
Let's imagine a use case: a User made a payment. You need to handle this payment, register the user, send him emails, send analytics data to your analysis system, and so on. The modern infrastructure requires you to create microservices that do their specific job and only it: one handles payments, one is for user management, one is the mailing system, one is for analysis. How to let all of them know that a payment succeeded and handle this message? The answer is "To use RabbitEvents".
Once again, the RabbitEvents library helps you publish an event and handle it in another app. It doesn't make sense to use it in the same app because Laravel's Events work better for that.
Demo
Table of Contents
- Installation via Composer
- Upgrade from 8.x to 9.x
- Publisher component
- Listener component
- Listeners & Payloads
- Custom Serializers
- Extensions
- Examples
- Speeding up RabbitEvents
- Testing
- Non-standard use
- License
Installation via Composer
You can use Composer to install RabbitEvents into your Laravel project:
composer require nuwber/rabbitevents
Configuration
After installing RabbitEvents, publish its config and a service provider using the rabbitevents:install Artisan command:
php artisan rabbitevents:install
This command installs the config file at config/rabbitevents.php and the Service Provider file at app/providers/RabbitEventsServiceProvider.php.
The config file is very similar to the queue connection, but with the separate config, you'll never be confused if you have another connection to RabbitMQ.
<?php use Enqueue\AmqpTools\RabbitMqDlxDelayStrategy; return [ 'default' => env('RABBITEVENTS_CONNECTION', 'rabbitmq'), /* |-------------------------------------------------------------------------- | Default Serializer |-------------------------------------------------------------------------- | | The default serializer to use when publishing messages. | Supported: "json", "protobuf" or any class implementing Serializer interface. | */ 'default_serializer' => \RabbitEvents\Foundation\Serialization\JsonSerializer::class, 'connections' => [ 'rabbitmq' => [ 'driver' => 'rabbitmq', 'exchange' => env('RABBITEVENTS_EXCHANGE', 'events'), 'durable' => env('RABBITEVENTS_QUEUE_DURABLE', true), 'host' => env('RABBITEVENTS_HOST', 'localhost'), 'port' => env('RABBITEVENTS_PORT', 5672), 'user' => env('RABBITEVENTS_USER', 'guest'), 'pass' => env('RABBITEVENTS_PASSWORD', 'guest'), 'vhost' => env('RABBITEVENTS_VHOST', 'events'), 'delay_strategy' => env('RABBITEVENTS_DELAY_STRATEGY', RabbitMqDlxDelayStrategy::class), 'ssl' => [ 'is_enabled' => env('RABBITEVENTS_SSL_ENABLED', false), 'verify_peer' => env('RABBITEVENTS_SSL_VERIFY_PEER', true), 'cafile' => env('RABBITEVENTS_SSL_CAFILE'), 'local_cert' => env('RABBITEVENTS_SSL_LOCAL_CERT'), 'local_key' => env('RABBITEVENTS_SSL_LOCAL_KEY'), 'passphrase' => env('RABBITEVENTS_SSL_PASSPHRASE', ''), ], 'read_timeout' => env('RABBITEVENTS_READ_TIMEOUT', 3.), 'write_timeout' => env('RABBITEVENTS_WRITE_TIMEOUT', 3.), 'connection_timeout' => env('RABBITEVENTS_CONNECTION_TIMEOUT', 3.), 'heartbeat' => env('RABBITEVENTS_HEARTBEAT', 0), 'persisted' => env('RABBITEVENTS_PERSISTED', false), 'lazy' => env('RABBITEVENTS_LAZY', true), 'qos' => [ 'global' => env('RABBITEVENTS_QOS_GLOBAL', false), 'prefetch_size' => env('RABBITEVENTS_QOS_PREFETCH_SIZE', 0), 'prefetch_count' => env('RABBITEVENTS_QOS_PREFETCH_COUNT', 1), ] ], ], 'logging' => [ 'enabled' => env('RABBITEVENTS_LOG_ENABLED', false), 'level' => env('RABBITEVENTS_LOG_LEVEL', 'info'), 'channel' => env('RABBITEVENTS_LOG_CHANNEL'), ], ];
Upgrade from 8.x to 9.x
PHP 8.2 required
RabbitEvents now requires PHP 8.2 or greater. It uses readonly classes and Enums.
Payload System Refactor
The internal payload handling has been refactored. Message::payload() now returns a RabbitEvents\Foundation\Contracts\Payload object.
To get the raw value, use $message->payload->value().
Protobuf Support
RabbitEvents supports Google Protobuf messages via the rabbitevents/protobuf extension package.
Once installed, simply publish a Protobuf Message object, and it will be automatically serialized and hydrated on the listener side.
The system uses the type AMQP header to resolve the correct class.
Example:
use Google\Protobuf\StringValue; +$message = new StringValue(); +$message->setValue('Hello World'); + +publish('my.event', $message);
Dynamic Serializers
The correct serializer is now automatically selected based on the content_type header of the message.
application/json-> JSON Serializerapplication/x-protobuf-> Protobuf Serializer
Supported Laravel versions
RabbitEvents now supports Laravel 10.0 or greater.
Architecture Decoupling
Version 9.0 introduces a more abstract and extensible architecture.
- Decoupled Serialization: Serializers now use an abstract
TransportMessagecontract instead ofInterop\Amqp\AmqpMessage. This creates a cleaner separation between domain logic and the transport layer. - Abstract Message Factory: The
MessageFactoryhas been moved to the Foundation layer and is now pluggable. You can implement your ownTransportMessageFactoryto create messages from different sources (e.g., tailored for testing or other transports). - Transport Agnostic: The core
MessageandSenderclasses rely on internal contracts (RabbitEvents\Foundation\Contracts\*), avoiding strict dependencies onqueue-interop. Adapters are provided for AMQP. - Connection Class Moved:
RabbitEvents\Foundation\Connectionhas been moved toRabbitEvents\Foundation\Amqp\Connection. Update your type hints if you were using it directly.
Namespace Changes
We have reorganized the namespace structure for better clarity and standard compliance:
- Commands: All console commands have been moved to
Consolenamespaces.RabbitEvents\Foundation\Commands->RabbitEvents\Foundation\ConsoleRabbitEvents\Listener\Commands->RabbitEvents\Listener\ConsoleRabbitEvents\Publisher\Commands->RabbitEvents\Publisher\Console
- Releaser:
RabbitEvents\Foundation\Support\Releaserhas been moved toRabbitEvents\Listener\Support\Releaseras it is a listener-specific component.
Removed --connection option from the rabbitevents:listen command
The default connection is always used instead.
RabbitEvents Publisher
The RabbitEvents Publisher component provides an API to publish events across the application structure. More information about how it works can be found on the RabbitEvents Publisher page.
RabbitEvents Listener
The RabbitEvents Listener component provides an API to handle events that were published across the application structure. More information about how it works can be found on the RabbitEvents Listener page.
It supports:
- Manual Registration: using the
$listenarray. - Attributes: using
#[Listener]on classes or methods. - Auto-Discovery: automatically finding
#[Listener]attributes in your listeners directory.
Listeners & Payloads
How the payload is passed to your listener depends on the serialization format:
JSON (Default): The payload is decoded as an associative array.
public function handle(array $payload) { // $payload['key'] }
Protobuf: The payload is passed as the Message Object itself.
public function handle(\Google\Protobuf\Internal\Message $message) { // $message->getSomething() }
Custom Serializers
You can implement your own serializer by implementing RabbitEvents\Foundation\Contracts\Serializer and RabbitEvents\Foundation\Contracts\ContentType.
use RabbitEvents\Foundation\Contracts\Serializer; use RabbitEvents\Foundation\Contracts\ContentType; use RabbitEvents\Foundation\Contracts\Payload; class MySerializer implements Serializer { public function serialize($data): Payload { ... } public function deserialize($message): Payload { ... } public function contentType(): ContentType { return new MyContentType(); } public function canSerialize($payload): bool { ... } }
Register your serializer in a ServiceProvider:
$registry = $this->app->make(\RabbitEvents\Foundation\Serialization\SerializerRegistry::class); $registry->register(new MySerializer());
New serializers are prepended to the registry, so they can override default behavior if they claim the payload.
Extensions
- Protobuf Support - Provides official Google Protobuf serialization support. Required for using Protobuf messages.
Speeding up RabbitEvents
To enhance the performance of RabbitEvents, consider installing the php-amqp extension along with the enqueue/amqp-ext package.
By doing so, RabbitEvents will utilize the enqueue/amqp-ext package instead of the default enqueue/amqp-lib package.
This substitution is advantageous because the C-written php-amqp package significantly outperforms the PHP-written enqueue/amqp-lib package.
You can install the php-amqp extension using the following command:
pecl install amqp
or use the way you prefer. More about it can be found here.
Next, install the enqueue/amqp-ext package with the following command:
composer require enqueue/amqp-ext
No additional configuration is required.
Testing
We always write tests. Tests in our applications contain many mocks and fakes to test how events are published.
There is the PublishableEventTesting trait that provides assertion methods in an Event class that you want to test.
Event.php
<?php namespace App\BroadcastEvents; use RabbitEvents\Publisher\ShouldPublish; use RabbitEvents\Publisher\Support\Publishable; use RabbitEvents\Publisher\Support\PublishableEventTesting; class Event implements ShouldPublish { use Publishable; use PublishableEventTesting; public function __construct(private array $payload) { } public function publishEventKey(): string { return 'something.happened'; } public function toPublish(): array { return $this->payload; } }
Test.php
<?php use \App\RabbitEvents\Event; use \App\RabbitEvents\AnotherEvent; Event::fake(); $payload = [ 'key1' => 'value1', 'key2' => 'value2', ]; Event::publish($payload); Event::assertPublished('something.happened', $payload); AnotherEvent::assertNotPublished();
If the assertion does not pass, Mockery\Exception\InvalidCountException will be thrown.
Don't forget to call \Mockery::close() in tearDown or similar methods of your tests.
Non-standard use
If you're using only one part of RabbitEvents, you should know a few things:
-
You remember, we're using RabbitMQ as the transport layer. In the RabbitMQ Documentation, you can find examples of how to publish your messages using a routing key. This routing key is the event name, like
something.happenedfrom the examples above. -
RabbitEvents expects that a message body is a JSON-encoded array. Every element of an array will be passed to a Listener as a separate variable. For example:
[
{
"key": "value"
},
"string",
123
]
There are 3 elements in this array, so 3 variables will be passed to a Listener (an array, a string, and an integer). If an associative array is being passed, the Dispatcher wraps this array by itself.
License
RabbitEvents is open-sourced software licensed under the MIT license.