Install the Bundle
composer require arthem/rabbit-bundle
Enable Auto-Tagging
Add this to config/services.yaml to auto-tag event handlers:
services:
_instanceof:
Arthem\Bundle\RabbitBundle\Consumer\Event\EventMessageHandlerInterface:
tags: ['arthem_rabbit.event_handler']
First Use Case: Sending a Message
Inject the RabbitProducer service and publish a message with a type:
use Arthem\Bundle\RabbitBundle\Producer\RabbitProducerInterface;
public function __construct(private RabbitProducerInterface $producer) {}
public function publishEvent(string $eventType, array $payload): void
{
$this->producer->publish($eventType, $payload);
}
Create a Handler
Implement EventMessageHandlerInterface and tag it:
use Arthem\Bundle\RabbitBundle\Consumer\Event\EventMessageHandlerInterface;
class MyEventHandler implements EventMessageHandlerInterface
{
public function handle(string $eventType, array $payload): void
{
// Process logic
}
public function supportedTypes(): array
{
return ['my.event.type'];
}
}
Producer-Consumer Flow
RabbitProducerInterface to publish messages with a type (e.g., user.created).arthem_rabbit.event_handler tag. The bundle routes messages to the correct handler based on the type.Queue and Exchange Management
eventx-eventconfig/packages/arthem_rabbit.yaml:
arthem_rabbit:
queues:
- name: 'custom_queue'
exchange: 'x-custom'
routing_key: 'custom.#'
Handling Multiple Message Types
public function supportedTypes(): array
{
return ['type1', 'type2'];
}
Asynchronous Processing
Messenger component alongside this bundle for decoupled processing:
$this->producer->publish('async.task', ['data' => $payload]);
RabbitProducerInterface and handlers.LoggerInterface in handlers for observability:
use Psr\Log\LoggerInterface;
public function __construct(private LoggerInterface $logger) {}
RabbitProducerInterface or use a test RabbitMQ instance (e.g., rabbitmq:3 in Docker).Handler Discovery
arthem_rabbit.event_handler will silently ignore them.bin/console debug:container | grep arthem_rabbit.event_handler
Message Type Mismatch
public function handle(string $eventType, array $payload): void
{
if (!in_array($eventType, $this->supportedTypes())) {
$this->logger->warning("Unsupported event type: {$eventType}");
return;
}
// Process...
}
Failure Tracking Overhead
failure: true in config adds Doctrine ORM dependency and database writes.arthem_rabbit:
failure: false # Default
RabbitMQ Connection Issues
php-amqplib/rabbitmq-bundle under the hood. Ensure your config/packages/rabbitmq.yaml is correctly configured:
rabbitmq:
hosts:
tcp://guest:guest@localhost:5672
bin/console debug:container | grep consumer
# config/packages/dev/arthem_rabbit.yaml
arthem_rabbit:
debug: true
Custom Exchanges/Queues Extend the bundle’s configuration to add new queues/exchanges:
arthem_rabbit:
queues:
- name: 'notifications'
exchange: 'x-notifications'
routing_key: 'notification.#'
Custom Failure Entity
Override BaseFailedEvent to add custom fields:
class CustomFailedEvent extends BaseFailedEvent
{
#[ORM\Column(type: 'string', nullable: true)]
private ?string $customField = null;
// Getters/Setters...
}
Middleware for Handlers Use Symfony’s middleware pattern to pre/post-process messages:
use Symfony\Component\HttpKernel\Middleware\MiddlewareInterface;
class LogHandlerMiddleware implements MiddlewareInterface
{
public function handle(Request $request, callable $next): Response
{
// Log before/after handler execution
return $next($request);
}
}
Retry Logic Implement retry logic in handlers using a decorator pattern:
class RetryHandlerDecorator implements EventMessageHandlerInterface
{
public function __construct(private EventMessageHandlerInterface $handler) {}
public function handle(string $eventType, array $payload): void
{
try {
$this->handler->handle($eventType, $payload);
} catch (Exception $e) {
// Retry logic...
}
}
public function supportedTypes(): array
{
return $this->handler->supportedTypes();
}
}
How can I help you explore Laravel packages today?