diffhead/laravel-rabbitmq

A laravel package for events emitting between services using RabbitMQ as message broker.

Installs: 20

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/diffhead/laravel-rabbitmq

1.0.0 2025-12-12 08:44 UTC

This package is auto-updated.

Last update: 2025-12-12 08:44:35 UTC


README

A package for working with RabbitMQ messages as Laravel events. Automatically serialize and publish events to RabbitMQ, and consume messages from queues by converting them back into events.

Features

Automatic event serialization — Events implementing the Broadcast interface are automatically serialized and sent to RabbitMQ Message consumption — Command to consume messages from RabbitMQ with automatic deserialization and event dispatching Default bindings — The BroadcastEvent trait sets standard connection parameters for an event Flexible configuration — Support for multiple connections and parameterization for each event Microservices architecture — Ideal for data exchange between services

Requirements

  • PHP 8.1+
  • Laravel 10, 11 or 12
  • RabbitMQ server

Installation

Install via Composer:

composer require diffhead/laravel-rabbitmq

The package will be automatically registered thanks to Laravel Service Provider Discovery.

Configuration

Publish the configuration file:

php artisan vendor:publish --provider="Diffhead\PHP\LaravelRabbitMQ\ServiceProvider"

ThisEnvironment Variables

# RabbitMQ Connection
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_USER=guest
RABBITMQ_PASSWORD=guest
RABBITMQ_VHOST=/

# Default event parameters
RABBITMQ_EVENT_CONNECTION=default
RABBITMQ_EVENT_QUEUE=default
RABBITMQ_EVENT_EXCHANGE=amq.direct
RABBITMQ_EVENT_EXCHANGE_TYPE=direct
RABBITMQ_EVENT_EXCHANGE_IS_DEFAULT=true
RABBITMQ_EVENT_ROUTING_KEY=

Configuration Example

return [
    'connections' => [
        'default' => [
            'host' => env('RABBITMQ_HOST', 'localhost'),
            'port' => env('RABBITMQ_PORT', 5672),
            'user' => env('RABBITMQ_USER', 'guest'),
            'password' => env('RABBITMQ_PASSWORD', 'guest'),
            'vhost' => env('RABBITMQ_VHOST', '/'),
        ],
        'secondary' => [
            'host' => env('RABBITMQ_SECONDARY_HOST', 'localhost'),
            'port' => env('RABBITMQ_SECONDARY_PORT', 5672),
            'user' => env('RABBITMQ_SECONDARY_USER', 'guest'),
            'password' => env('RABBITMQ_SECONDARY_PASSWORD', 'guest'),
            'vhost' => env('RABBITMQ_SECONDARY_VHOST', '/'),
        ]
    ],
    'message' => [
        'serializer' => \Diffhead\PHP\LaravelRabbitMQ\Service\Serializer::class,
        'unserializer' => \Diffhead\PHP\LaravelRabbitMQ\Service\Unserializer::class,
    ],
    'event' => [
        'defaults' => [
            'connection' => env('RABBITMQ_EVENT_CONNECTION', 'default'),
            'queue' => env('RABBITMQ_EVENT_QUEUE', 'default'),
            'exchange' => env('RABBITMQ_EVENT_EXCHANGE', 'amq.direct'),
            'exchange_type' => env('RABBITMQ_EVENT_EXCHANGE_TYPE', 'direct'),
            'exchange_is_default' => (bool) env('RABBITMQ_EVENT_EXCHANGE_IS_DEFAULT', true),
            'routing_key' => env('RABBITMQ_EVENT_ROUTING_KEY', ''),
        ],
        'mapper' => \Diffhead\PHP\LaravelRabbitMQ\Service\EventMapper::class,
        'map' => [
            /**
             * Map events to queues and routing keys
             */
            \App\Events\User\UserCreated::class => [
                'queues' => ['portal.users'],
                'routing_keys' => ['user.created'],
            ],
            \App\Events\Meeting\MeetingCreated::class => [
                'queues' => ['portal.meetings'],
                'routing_keys' => ['meeting.created'],
            ],
        ],
    ]
];

Usage

1. Creating an Event for Publishing to RabbitMQ

Create an event that implements the Broadcast interface:

namespace App\Events;

use Diffhead\PHP\LaravelRabbitMQ\Event\Broadcast;
use Diffhead\PHP\LaravelRabbitMQ\Trait\BroadcastEvent;
use Illuminate\Foundation\Events\Dispatchable;

class UserCreated implements Broadcast
{
    use Dispatchable, BroadcastEvent;

    public function __construct(
        public int $userId,
        public string $email,
        public string $name,
    ) {}

    public function jsonSerialize(): array
    {
        return [
            'userId' => $this->userId,
            'email' => $this->email,
            'name' => $this->name,
        ];
    }
}

Event Parameters

When implementing the Broadcast interface, you must define the following methods:

  • getConnection(): string — RabbitMQ connection name
  • getQueue(): string — Queue name
  • getExchange(): string — Exchange name
  • getExchangeType(): string — Exchange type (direct, topic, fanout, headers)
  • getExchangeIsDefault(): bool — Whether to use the default exchange
  • getRoutingKey(): string — Routing key for the message

Using the BroadcastEvent Trait

The BroadcastEvent trait provides implementations of all methods using default parameters from configuration:

namespace App\Events;

use Diffhead\PHP\LaravelRabbitMQ\Event\Broadcast;
use Diffhead\PHP\LaravelRabbitMQ\Trait\BroadcastEvent;

class UserCreated implements Broadcast
{
    use BroadcastEvent;

    public function __construct(
        public int $userId,
        public string $email,
    ) {}

    public function jsonSerialize(): array
    {
        return [
            'userId' => $this->userId,
            'email' => $this->email,
        ];
    }
}

If you need special parameters for a specific event, override the necessary methods:

namespace App\Events;

use Diffhead\PHP\LaravelRabbitMQ\Event\Broadcast;
use Diffhead\PHP\LaravelRabbitMQ\Trait\BroadcastEvent;

class CriticalAlert implements Broadcast
{
    use BroadcastEvent;

    public function __construct(
        public string $message,
    ) {}

    public function getRoutingKey(): string
    {
        return 'alert.critical';
    }

    public function getExchange(): string
    {
        return 'alerts.topic';
    }

    public function getExchangeType(): string
    {
        return 'topic';
    }

    public function jsonSerialize(): array
    {
        return [
            'message' => $this->message,
        ];
    }
}

2. Publishing Events

Events are automatically published when dispatched:

use App\Events\UserCreated;

/** 
 * Events implementing Broadcast are automatically sent to RabbitMQ
 */
UserCreated::dispatch(userId: 1, email: 'user@example.com', name: 'John Doe');

3. Consuming Messages from RabbitMQ

Use the rabbitmq:consume command to listen for messages:

#####################################################################################
#
# Has following options:
#
# --connection=default        - Connection name from config
# --queue=default             - Queue
# --exchange=amq.direct       - Exchange name
# --exchange-type=direct      - Exchange type
# --exchange-is-default       - Exchange is default, required for default exchanges
# --routing-key=user.*        - Listen routing keys, required for topic exchanges
# --tag=myconsumer            - Consumer tag for rabbitmq
#
#####################################################################################

php artisan rabbitmq:consume

Full Consumer Startup Example

php artisan rabbitmq:consume \
  --connection=default \
  --queue=service.users \
  --exchange=amq.direct \
  --exchange-type=direct \
  --routing-key=user.* \
  --tag=service-users-consumer

4. Handling Received Events

When a message is received from RabbitMQ, it is automatically deserialized and dispatched as a Laravel event. You can listen to these events normally:

namespace App\Listeners;

use App\Events\UserCreated;
use Illuminate\Support\Log;

class SendWelcomeEmail
{
    public function handle(UserCreated $event): void
    {
        Log::info("User created: {$event->email}");
    }
}

Register the listener in app/Providers/EventServiceProvider.php:

protected $listen = [
    \App\Events\UserCreated::class => [
        \App\Listeners\SendWelcomeEmail::class,
    ],
];

Architecture

Event Publishing Flow

Laravel Event (Broadcast) 
    ↓
PublishEvent (Listener)
    ↓
Serializer (JSON)
    ↓
RabbitMQ Exchange
    ↓
Queue

Message Consumption Flow

RabbitMQ Queue
    ↓
Message Consumer
    ↓
Unserializer (JSON)
    ↓
EventMapper (Event)
    ↓
EventEmitter (Service)
    ↓
Event Listeners

Microservices Architecture Example

Service 1: Publishes event

namespace App\Events;

use Diffhead\PHP\LaravelRabbitMQ\Event\Broadcast;
use Diffhead\PHP\LaravelRabbitMQ\Trait\BroadcastEvent;

class UserCreated implements Broadcast
{
    use BroadcastEvent;

    public function __construct(
        public int $id,
        public string $email,
        public string $name,
    ) {}

    public function getRoutingKey(): string
    {
        return 'user.created';
    }

    public function jsonSerialize(): array
    {
        return [
            'id' => $this->id,
            'email' => $this->email,
            'name' => $this->name,
        ];
    }
}
use App\Events\UserCreated;

/**
 * Controller method
 */
public function store(Request $request)
{
    $user = User::create($request->validated());
    UserCreated::dispatch($user->id, $user->email, $user->name);
    
    return response()->json($user, 201);
}

Service 2: Receives event

Map event using configuration:

'map' => [
    \App\Events\UserCreated::class => [
        'queues' => ['service2.users'],
        'routing_keys' => ['user.created']
    ]
]

Then implement and register event listener:

namespace App\Listeners;

use App\Events\UserCreated;

class SyncUserToCalendar
{
    public function handle(UserCreated $event): void
    {
        CalendarUser::create([
            'external_id' => $event->id,
            'email' => $event->email,
            'name' => $event->name,
        ]);
    }
}

Start consumer

php artisan rabbitmq:consume --queue=service2.users --routing-key=user.* --exchange=amq.topic --exchange-type=topic --exchange-is-default

Serialization

The package uses JSON for serialization/deserialization of data via Serializer and Unserializer interfaces.

Custom Serialization

You can use your own serialization classes by implementing interfaces and overriding following configuration entities:

'message' => [
    'serializer' => \App\Services\CustomSerializer::class,
    'unserializer' => \App\Services\CustomUnserializer::class,
],

Mapping

The package maps rabbitmq message to application events

Custom mapping

You can use your own mapping logic by implementing EventMapper
interface and overriding the following configuration entity:

'event' => [
    'mapper' => \App\Services\CustomEventMapper::class,
]