Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Rabbit Laravel Package

sobirjonovs/laravel-rabbit

Laravel Rabbit offers simple RabbitMQ integration for Laravel apps, helping you publish and consume messages, configure queues and exchanges, and build reliable background messaging workflows with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, low-traffic package (11 stars, last release Aug 2024), so treat the source and README as the primary documentation and verify class names before building on them. The workflow below reflects the package's stated purpose — a thin, easy wrapper around RabbitMQ for Laravel — and typical patterns for packages of this shape.

1. Install and publish

composer require sobirjonovs/laravel-rabbit
php artisan vendor:publish --provider="Sobirjonovs\LaravelRabbit\...ServiceProvider"

Laravel auto-discovery should register the service provider; check composer.json of the package for the extra.laravel.providers block and the facade alias. If the provider is not auto-discovered, register it manually in bootstrap/providers.php (Laravel 11+) or config/app.php.

2. Configure the connection

Start in the published config file (likely config/rabbit.php or config/laravel-rabbit.php). You need at minimum:

  • host, port (5672 / 5671 for TLS), vhost
  • username / password (default guest/guest only works on localhost)
  • exchange name, exchange type (direct, topic, fanout, headers)
  • queue name(s) and routing/binding keys
  • heartbeat and connection timeout

Put credentials in .env (RABBITMQ_HOST, RABBITMQ_PORT, RABBITMQ_USER, RABBITMQ_PASSWORD, RABBITMQ_VHOST) and reference them from the config. Never commit production vhost credentials.

3. Where to look first

  • README.md — installation, the facade name, and the publish/consume example.
  • config/*.php — the actual list of knobs the package supports; this is the ground truth for what is configurable vs. hardcoded.
  • src/ — look for the connection factory, the facade root class, any Console/Commands directory (consumer commands), and any Jobs/Messages classes. This tells you whether the package gives you a consumer command or expects you to write one.
  • tests/ — even sparse tests reveal expected payload shapes and method signatures.

4. First use case: publish from a controller, consume from a command

The fastest end-to-end validation is a single queue, a single exchange, and one consumer:

// publishing
use Sobirjonovs\LaravelRabbit\Facades\Rabbit; // confirm exact namespace

Rabbit::publish('orders', json_encode([
    'event' => 'order.created',
    'id'    => $order->id,
    'ts'    => now()->toIso8601String(),
]));

Then confirm the message landed by opening the RabbitMQ management UI (http://localhost:15672) and inspecting the queue. Only after you see the message should you wire up a consumer:

php artisan rabbit:consume orders   # confirm the actual command signature

If the package does not ship a consumer command, you write one yourself using php-amqplib/php-amqplib-style basic_consume against the package's connection object — check src/ for a connection() or channel() accessor.

Recommended first milestone: publish one message, see it in the management UI, consume it, ack it, and confirm the queue depth returns to zero. Do this before integrating with domain events.

Implementation Patterns

Publishing from domain events, not controllers. Keep HTTP controllers thin. Publish from a Laravel event listener so the same message is emitted whether the action came from HTTP, a command, or a scheduled job:

// app/Listeners/PublishOrderCreated.php
public function handle(OrderCreated $event): void
{
    Rabbit::publish('orders', json_encode([
        'event'      => 'order.created',
        'id'         => $event->order->id,
        'occurred_at'=> $event->order->created_at->toIso8601String(),
        'trace_id'   => $event->traceId,
    ]));
}

Register the listener against the event and dispatch the event after the DB transaction commits (DB::afterCommit() or Event::dispatch inside DB::transaction's success path). Publishing inside a transaction that later rolls back is a classic phantom-message bug.

Separate publishers and consumers into different processes. Publishers live in the web app; consumers run as long-lived CLI workers under Supervisor or a container orchestrator. Do not consume inside an HTTP request — it blocks the worker and defeats the purpose of the queue.

Topology declaration belongs at deploy time. Exchanges, queues, bindings, and dead-letter wiring should be declared once (a deploy step, a bootstrap command, or an infrastructure-as-code step), not on every publish. Declaring durable queues on each message is slow and racy. If the package offers a declare/setup command, run it in your deploy pipeline after migrations.

Message contract. Agree on a JSON envelope across services:

{
  "event": "order.created",
  "id": 1234,
  "occurred_at": "2024-08-10T12:00:00Z",
  "trace_id": "abc-123",
  "payload": { }
}

Routing key = event name (with a topic exchange) makes consumer filters trivial and keeps bindings declarative. Always include a stable message ID for consumer-side idempotency.

Consumer pattern: idempotent, bounded, observable.

public function handle(array $message): void
{
    $key = $message['event'] . ':' . $message['id'];

    if (Cache::has("consumed:$key")) {
        return; // already processed
    }

    DB::transaction(function () use ($message) {
        // handle
        Cache::put("consumed:$key", true, now()->addDay());
    });
}

Wrap the handler body in try/catch, log with the trace_id, and decide explicitly between ack, nack(requeue: true), and nack(requeue: false) → DLX. Never leave an unhandled exception to silently drop a message.

Integrating with Laravel's queue system. Note that Laravel ships no native RabbitMQ queue driver. This package is a direct AMQP wrapper, not a Queue driver, so dispatch(new Job) will not go through RabbitMQ. If you want Laravel's queue semantics (ShouldQueue, retries, failed_jobs) on top of RabbitMQ, the common choice is a dedicated driver package such as vladimir-yuldashev/laravel-queue-rabbitmq, and it is generally a mistake to run both mechanisms against the same queue. Pick one: either use this package's publish/consume API as a lightweight event bus alongside Laravel's default queue, or use a proper queue driver. Don't mix.

Testing. Don't hit a real broker in unit tests. Either:

  • Bind a fake into the container in TestCase::setUp() and assert on published payloads, or
  • Run a real RabbitMQ in CI (docker run -d -p 5672:5672 rabbitmq:3-management) and use the management API to assert queue depth and drain messages between tests.

Tag integration tests so local runs without Docker skip them.

Config per environment. Keep exchange/queue names different per environment (e.g., orders.production, orders.staging) or use separate vhosts. Sharing a vhost across staging and production is the most common way to accidentally consume production traffic in a staging worker.

Gotchas and Tips

Maturity and maintenance risk. With 11 stars and a single 2024-08-10 release, assume the package is a thin convenience layer rather than a battle-tested abstraction. Pin the exact version in composer.json, read the source before relying on anything not documented, and be prepared to fork or replace it. Confirm it installs cleanly against your Laravel and PHP versions — older packages frequently break on Laravel 11/12 because of service-provider signature changes or missing illuminate/support constraints.

Channel and connection lifecycle. AMQP connections are long-lived; channels are not thread-safe and should not be shared across processes. If the package memoizes a single connection, long-running consumers will hit Broken pipe, connection reset by peer, or heartbeat timeout after idle periods. Handle reconnect: catch the connection exception, drop the channel, reconnect, and retry once. Set the client heartbeat higher than any expected consumer-blocking work.

Consumer memory leaks. In a while loop, PHP references accumulate. Unset the message body and any large payload arrays each iteration, and consider restarting the worker every N messages (max-messages style) rather than running indefinitely. Long-running workers also hold stale DB connections — reconnect or set DB::purge() periodically, or you'll see MySQL server has gone away mid-consume.

php artisan config:cache quirks. If you deploy with cached config, the package's config file must not use closures or non-serializable values. After changing env vars, re-run php artisan config:clear && php artisan config:cache, otherwise your worker silently keeps the old vhost credentials.

Ack/nack and requeue loops. The single biggest production failure with hand-rolled consumers is a message that always throws: nack(requeue: true) puts it back at the head of the queue and the worker spins forever. Always prefer requeue: false plus a dead-letter exchange, or use a retry count in a header with a TTL backoff queue. Set a max-attempt policy explicitly.

Durability is a set of choices, not a default. A durable queue with a non-persistent message still loses data on broker restart. Configure the exchange as durable, the queue as durable, and publish with delivery_mode: 2. This requires the package to expose those options — check the config and the publish signature; if they aren't exposed, that's a reason to fork.

Publisher confirms. For anything you can't afford to lose, enable publisher confirms on the channel and handle basic.nack from the broker. Fire-and-forget basic_publish into a closed socket returns success locally while the broker never saw the message. If the package doesn't support confirms, wrap publishing in an outbox table and republish after commit.

Guest user is localhost-only. guest/guest will be rejected from any non-loopback address. If your app container can't reach the broker, check vhost permissions (rabbitmqctl set_permissions -p / user ".*" ".*" ".*") and that the user is allowed to configure the exchange you're declaring.

Deployment and shutdown. Supervisor/systemd should send SIGTERM and let the worker finish its in-flight message, ack, and exit — not SIGKILL mid-handler. php artisan queue:restart does not restart custom consumers; you need your own restart mechanism (a sentinel cache key checked each loop, or an orchestrator rolling restart).

Extension points. Because the package is thin, the reliable extension points are: (1) subclass or decorate the connection factory and bind your own implementation in a service provider, (2) add your own consumer command in app/Console/Commands that reuses the package's connection/channel accessor, and (3) wrap publishing behind your own MessageBus interface so you can swap in a different broker client later without touching call sites. Do that wrapper from day one — it is the cheapest insurance against this package's small maintainer base.

Debugging checklist. When a message "disappears": verify the exchange type matches the routing key, check bindings in the management UI, confirm the queue is not auto-deleting, check for an unacked message stuck in a dead consumer (consumers and unacked columns in the UI), and tail the package's log channel. If you can't see publish errors, enable APP_DEBUG locally and add a try/catch around publish() that logs the AMQP exception code — the wrapper may swallow it.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator