{"id":50519641,"url":"https://github.com/push-in/laravel-rabbit","last_synced_at":"2026-06-03T03:05:02.858Z","repository":{"id":358690784,"uuid":"1242591371","full_name":"push-in/laravel-rabbit","owner":"push-in","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-18T15:43:25.000Z","size":78,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-18T17:33:33.547Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/push-in.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-18T15:08:01.000Z","updated_at":"2026-05-18T15:43:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/push-in/laravel-rabbit","commit_stats":null,"previous_names":["push-in/laravel-rabbit"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/push-in/laravel-rabbit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-in%2Flaravel-rabbit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-in%2Flaravel-rabbit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-in%2Flaravel-rabbit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-in%2Flaravel-rabbit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/push-in","download_url":"https://codeload.github.com/push-in/laravel-rabbit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-in%2Flaravel-rabbit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33845775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-03T03:05:02.417Z","updated_at":"2026-06-03T03:05:02.849Z","avatar_url":"https://github.com/push-in.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel Rabbit\n\n[![Tests](https://github.com/push-in/laravel-rabbit/actions/workflows/tests.yml/badge.svg)](https://github.com/push-in/laravel-rabbit/actions/workflows/tests.yml)\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/pushinbr/laravel-rabbit.svg)](https://packagist.org/packages/pushinbr/laravel-rabbit)\n[![Total Downloads](https://img.shields.io/packagist/dt/pushinbr/laravel-rabbit.svg)](https://packagist.org/packages/pushinbr/laravel-rabbit)\n[![License](https://img.shields.io/github/license/push-in/laravel-rabbit.svg)](LICENSE.md)\n\nRabbitMQ library for Laravel with a native queue driver, AMQP 0-9-1 publishing and consuming, topology declarations, TLS, publisher confirms, QoS, host failover, RabbitMQ Management HTTP API support, and security validation.\n\n```php\nuse App\\Jobs\\ProcessOrder;\n\nProcessOrder::dispatch($order)-\u003eonQueue('orders');\n```\n\n\u003e [!IMPORTANT]\n\u003e The package registers a Laravel queue driver named `rabbitmq`. When `QUEUE_CONNECTION=rabbitmq`, Laravel's native `dispatch()`, `onQueue()`, `delay()`, `queue:work`, retries, backoff, failed jobs, batches, chained jobs, and unique jobs continue to work through the standard Laravel worker flow.\n\n## Table of Contents\n\n- [Compatibility](#compatibility)\n- [Feature Overview](#feature-overview)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Laravel Queue Driver](#laravel-queue-driver)\n- [Delayed Jobs](#delayed-jobs)\n- [RabbitMQ Management API](#rabbitmq-management-api)\n- [Artisan Commands](#artisan-commands)\n- [Low-Level AMQP Usage](#low-level-amqp-usage)\n- [Topology](#topology)\n- [Production Options](#production-options)\n- [Security](#security)\n- [Testing](#testing)\n\n## Compatibility\n\n| Component | Supported Versions | Notes |\n| --- | --- | --- |\n| PHP | `^8.2` | Tested on modern PHP versions used by Laravel 11, 12, and 13. |\n| Laravel | `^11.0`, `^12.0`, `^13.0` | Package discovery registers the service provider and facade automatically. |\n| Queue system | Laravel Queue | Adds `queue.connections.rabbitmq` and works with the normal worker commands. |\n| AMQP driver | `php-amqplib/php-amqplib ^3.7` | Used for AMQP 0-9-1 connections and messages. |\n| RabbitMQ | RabbitMQ 3.x and 4.x compatible AMQP API | Management API metrics require the RabbitMQ management plugin. |\n\n## Feature Overview\n\n| Area | Included |\n| --- | --- |\n| Laravel queue driver | `dispatch()`, `onQueue()`, `delay()`, `release()`, `queue:work`, `queue:clear`, `tries`, `backoff`, `timeout`, `retryUntil`, failed jobs, batches, chained jobs, and unique jobs. |\n| AMQP publishing | Plain text, JSON, headers, message properties, mandatory publish, and publisher confirms. |\n| AMQP consuming | Callback consumers, `basic_get`, ack, nack, reject, idle timeout, max messages, and stop when empty. |\n| Delay support | TTL dead-letter queues by default, optional `x-delayed-message` exchange strategy. |\n| Broker topology | Exchanges, queues, bindings, queue arguments, exchange arguments, and automatic declarations. |\n| Operations | `rabbitmq:install`, `rabbitmq:check`, `rabbitmq:setup`, `rabbitmq:stats`, `rabbitmq:management`, `rabbitmq:doctor`, `rabbitmq:consume-test`, and `rabbitmq:purge`. |\n| Management API | Overview, nodes, queues, queue metrics, exchanges, consumers, bindings, users, permissions, definitions, aliveness test, and generic HTTP requests. |\n| Security | Queue payload signing, TLS policy, remote `guest` guard, message size guard, Management API TLS policy, and config sanitization. |\n| Reliability | Publisher confirms, QoS/prefetch, heartbeat, timeouts, host failover, reconnect attempts, and return listeners. |\n\n## Installation\n\nInstall the package:\n\n```bash\ncomposer require pushinbr/laravel-rabbit\n```\n\nPublish the configuration file:\n\n```bash\nphp artisan vendor:publish --tag=laravel-rabbit-config\n```\n\nOr use the installer command:\n\n```bash\nphp artisan rabbitmq:install\n```\n\nLaravel auto-discovery registers:\n\n| Binding | Purpose |\n| --- | --- |\n| `Pushin\\LaravelRabbit\\LaravelRabbit` | Main package service. |\n| `laravel-rabbit` | Container alias for the main service. |\n| `laravel-rabbit.manager` | Connection manager alias. |\n| `laravel-rabbit.management` | RabbitMQ Management API client alias. |\n| `LaravelRabbit` facade | Optional facade shortcut. |\n\n```php\nuse Pushin\\LaravelRabbit\\Facades\\LaravelRabbit;\n```\n\n## Quick Start\n\n### 1. Configure RabbitMQ\n\n```dotenv\nQUEUE_CONNECTION=rabbitmq\n\nLARAVEL_RABBIT_CONNECTION=default\nRABBITMQ_HOST=127.0.0.1\nRABBITMQ_PORT=5672\nRABBITMQ_VHOST=/\nRABBITMQ_USER=guest\nRABBITMQ_PASSWORD=guest\nRABBITMQ_QUEUE=default\nRABBITMQ_EXCHANGE=\nRABBITMQ_ROUTING_KEY=\n```\n\n\u003e [!TIP]\n\u003e Leave `RABBITMQ_QUEUE_ROUTING_KEY` unset for most Laravel apps. The package will use the queue name from `onQueue()` as the routing key.\n\nOptional payload signing for the queue driver:\n\n```dotenv\nRABBITMQ_QUEUE_SIGN_PAYLOADS=true\nRABBITMQ_QUEUE_SIGNING_KEY=\"${APP_KEY}\"\nRABBITMQ_QUEUE_INVALID_SIGNATURE_REQUEUE=false\n```\n\n\u003e [!IMPORTANT]\n\u003e Payload signing protects the Laravel worker from unsigned or tampered queue messages. Enable it only after all producers that publish Laravel jobs through RabbitMQ use the same signing key, because unsigned existing messages will be rejected when verification is enabled.\n\n### 2. Dispatch a Job\n\n```php\nuse App\\Jobs\\ProcessOrder;\n\nProcessOrder::dispatch($order)-\u003eonQueue('orders');\n```\n\n### 3. Run the Worker\n\n```bash\nphp artisan queue:work --queue=orders\n```\n\nBecause `QUEUE_CONNECTION=rabbitmq`, the command above uses RabbitMQ without passing the connection name. This also works:\n\n```bash\nphp artisan queue:work rabbitmq --queue=orders\n```\n\n### 4. Check the Setup\n\n```bash\nphp artisan rabbitmq:doctor\nphp artisan rabbitmq:stats orders\n```\n\n## Laravel Queue Driver\n\nThe `laravel_queue` config section is merged automatically into `queue.connections.rabbitmq`.\n\n```php\n'laravel_queue' =\u003e [\n    'driver' =\u003e 'rabbitmq',\n    'rabbit_connection' =\u003e env('LARAVEL_RABBIT_CONNECTION', 'default'),\n    'queue' =\u003e env('RABBITMQ_QUEUE', 'default'),\n    'exchange' =\u003e env('RABBITMQ_QUEUE_EXCHANGE', env('RABBITMQ_EXCHANGE', '')),\n    'exchange_type' =\u003e env('RABBITMQ_QUEUE_EXCHANGE_TYPE', 'direct'),\n    'routing_key' =\u003e env('RABBITMQ_QUEUE_ROUTING_KEY'),\n    'declare' =\u003e true,\n    'durable' =\u003e true,\n    'delivery_mode' =\u003e 2,\n    'after_commit' =\u003e false,\n    'retry_after' =\u003e 90,\n    'security' =\u003e [\n        'sign_payloads' =\u003e false,\n        'verify_payload_signatures' =\u003e false,\n        'signing_key' =\u003e env('APP_KEY'),\n        'invalid_signature_requeue' =\u003e false,\n    ],\n    'delay' =\u003e [\n        'strategy' =\u003e 'ttl',\n        'queue_prefix' =\u003e 'laravel.delay.',\n    ],\n],\n```\n\n### Laravel Support Matrix\n\n| Laravel feature | Status | Implementation detail |\n| --- | --- | --- |\n| `dispatch()` | Supported | Publishes a Laravel queue payload to RabbitMQ. |\n| `dispatch()-\u003eonQueue('orders')` | Supported | Uses `orders` as the RabbitMQ queue and default routing key. |\n| `delay()` / `later()` | Supported | Uses TTL dead-letter queues by default. |\n| `release($delay)` | Supported | Republishes with incremented attempts and acknowledges the original delivery. |\n| `$tries` | Supported | Enforced by Laravel's worker. |\n| `backoff()` / `$backoff` | Supported | Enforced by Laravel's worker through `release($delay)`. |\n| `$timeout` | Supported | Enforced by Laravel's worker process. |\n| `retryUntil()` | Supported | Enforced by Laravel's worker. |\n| Failed jobs | Supported | Uses Laravel's configured failed job provider. |\n| Chained jobs | Supported | Laravel handles the chain metadata in the payload. |\n| Batches | Supported | Laravel handles batch metadata in the payload. |\n| Unique jobs | Supported | Laravel handles locks before enqueueing. |\n| `queue:work` | Supported | Works as `queue:work` when `QUEUE_CONNECTION=rabbitmq`. |\n| `queue:clear` | Supported | Purges the target RabbitMQ queue. |\n\n### Worker Examples\n\n| Goal | Command |\n| --- | --- |\n| Work the default RabbitMQ connection | `php artisan queue:work` |\n| Work one queue | `php artisan queue:work --queue=orders` |\n| Explicit RabbitMQ connection | `php artisan queue:work rabbitmq --queue=orders` |\n| Process one job | `php artisan queue:work --queue=orders --once` |\n| Clear a queue | `php artisan queue:clear rabbitmq --queue=orders` |\n| Retry failed jobs | `php artisan queue:retry all` |\n\n### Job Example\n\n```php\nnamespace App\\Jobs;\n\nuse Illuminate\\Contracts\\Queue\\ShouldQueue;\nuse Illuminate\\Foundation\\Queue\\Queueable;\n\nclass ProcessOrder implements ShouldQueue\n{\n    use Queueable;\n\n    public int $tries = 5;\n\n    public int $timeout = 60;\n\n    public function __construct(public int $orderId)\n    {\n    }\n\n    public function backoff(): array\n    {\n        return [10, 30, 60];\n    }\n\n    public function handle(): void\n    {\n        // Process the order.\n    }\n}\n```\n\n```php\nProcessOrder::dispatch($order-\u003eid)\n    -\u003eonQueue('orders')\n    -\u003edelay(now()-\u003eaddMinutes(5));\n```\n\n## Delayed Jobs\n\n| Strategy | Requires plugin | How it works | Metric support |\n| --- | --- | --- | --- |\n| `ttl` | No | Publishes to a per-delay TTL queue that dead-letters back to the target queue. | `delayed` can be calculated through the Management API. |\n| `x-delayed-message` | Yes | Publishes through RabbitMQ's delayed message exchange plugin. | RabbitMQ does not expose delayed exchange messages as queue depth. |\n| `none` | No | Publishes immediately. | No delayed count. |\n\nDefault strategy:\n\n```dotenv\nRABBITMQ_QUEUE_DELAY_STRATEGY=ttl\nRABBITMQ_QUEUE_DELAY_PREFIX=laravel.delay.\n```\n\nDelayed message exchange strategy:\n\n```dotenv\nRABBITMQ_QUEUE_DELAY_STRATEGY=x-delayed-message\nRABBITMQ_QUEUE_DELAY_EXCHANGE=laravel.delayed\n```\n\n## RabbitMQ Management API\n\nThe Management API integration is optional. The queue driver can dispatch and consume jobs without it. Enable it when you want broker-level metrics and operational visibility.\n\n```dotenv\nRABBITMQ_MANAGEMENT_ENABLED=true\nRABBITMQ_MANAGEMENT_SCHEME=http\nRABBITMQ_MANAGEMENT_HOST=127.0.0.1\nRABBITMQ_MANAGEMENT_PORT=15672\nRABBITMQ_MANAGEMENT_USER=guest\nRABBITMQ_MANAGEMENT_PASSWORD=guest\n```\n\n### Management Configuration\n\n| Env | Default | Description |\n| --- | --- | --- |\n| `RABBITMQ_MANAGEMENT_ENABLED` | `false` | Enables the Management API client. |\n| `RABBITMQ_MANAGEMENT_SCHEME` | `http` | Use `http` or `https`. |\n| `RABBITMQ_MANAGEMENT_HOST` | `RABBITMQ_HOST` or `127.0.0.1` | Management API host. |\n| `RABBITMQ_MANAGEMENT_PORT` | `15672` | Management API port. |\n| `RABBITMQ_MANAGEMENT_BASE_PATH` | empty | Optional reverse proxy base path. |\n| `RABBITMQ_MANAGEMENT_VHOST` | `RABBITMQ_VHOST` or `/` | Default virtual host for API calls. |\n| `RABBITMQ_MANAGEMENT_USER` | `RABBITMQ_USER` or `guest` | Management API user. |\n| `RABBITMQ_MANAGEMENT_PASSWORD` | `RABBITMQ_PASSWORD` or `guest` | Management API password. |\n| `RABBITMQ_MANAGEMENT_TIMEOUT` | `5.0` | HTTP timeout in seconds. |\n| `RABBITMQ_MANAGEMENT_VERIFY_TLS` | `true` | Verifies TLS peer and peer name for HTTPS. |\n| `RABBITMQ_MANAGEMENT_ALLOW_INSECURE_TLS` | `false` | Allows disabled HTTPS verification when explicitly needed. |\n| `RABBITMQ_MANAGEMENT_FORBID_GUEST_REMOTE` | `true` | Rejects `guest` on non-local hosts. |\n| `RABBITMQ_MANAGEMENT_CAFILE` | `RABBITMQ_SSL_CAFILE` | Optional CA file for HTTPS. |\n| `RABBITMQ_MANAGEMENT_CAPATH` | `RABBITMQ_SSL_CAPATH` | Optional CA path for HTTPS. |\n\n### Metrics Mapping\n\n| Laravel queue metric | RabbitMQ Management field | Fallback without Management API |\n| --- | --- | --- |\n| `size()` / `total` | `messages` | AMQP queue declaration message count. |\n| `pendingSize()` / `pending` | `messages_ready` | AMQP queue declaration message count. |\n| `reservedSize()` / `reserved` | `messages_unacknowledged` | `0` |\n| `delayedSize()` / `delayed` | Sum of matching TTL delay queues | `0` |\n\n\u003e [!NOTE]\n\u003e `delayedSize()` is accurate for this package's default TTL delay queues. RabbitMQ does not expose queued messages inside an `x-delayed-message` exchange as normal queue depth.\n\n### Management Client Usage\n\n```php\nuse Pushin\\LaravelRabbit\\Facades\\LaravelRabbit;\n\n$overview = LaravelRabbit::management()-\u003eoverview();\n$orders = LaravelRabbit::management()-\u003equeue('orders');\n$queues = LaravelRabbit::management()-\u003equeues('/');\n$nodes = LaravelRabbit::management()-\u003enodes();\n$definitions = LaravelRabbit::management()-\u003edefinitions();\n```\n\nCall any Management API endpoint directly:\n\n```php\n$policies = LaravelRabbit::management()-\u003eget('/api/policies/%2F');\n```\n\nUse non-GET endpoints through `request()`:\n\n```php\nLaravelRabbit::management()-\u003erequest('PUT', '/api/policies/%2F/ttl', body: [\n    'pattern' =\u003e '^orders\\\\.',\n    'definition' =\u003e ['message-ttl' =\u003e 60000],\n    'priority' =\u003e 0,\n    'apply-to' =\u003e 'queues',\n]);\n```\n\n## Artisan Commands\n\nLaravel's native queue commands remain the primary interface.\n\n| Command | Purpose |\n| --- | --- |\n| `php artisan queue:work --queue=orders` | Work the `orders` queue using RabbitMQ when `QUEUE_CONNECTION=rabbitmq`. |\n| `php artisan queue:work rabbitmq --queue=orders` | Work the `orders` queue with an explicit queue connection. |\n| `php artisan queue:clear rabbitmq --queue=orders` | Clear a queue through Laravel's native queue command. |\n| `php artisan queue:failed` | List failed jobs from Laravel's failed job provider. |\n| `php artisan queue:retry all` | Retry failed jobs through Laravel. |\n\nThe package also adds RabbitMQ-specific operational commands.\n\n| Command | Purpose | Safe for deploy checks |\n| --- | --- | --- |\n| `rabbitmq:install` | Publish config and print env examples. | No |\n| `rabbitmq:check` | Verify connection and optionally passively check a queue. | Yes |\n| `rabbitmq:setup` | Declare configured topology and optionally one queue-driver queue. | Yes, when declaration is expected. |\n| `rabbitmq:stats` | Show queue metrics through the Laravel queue driver. | Yes |\n| `rabbitmq:management` | Inspect broker overview, queues, or one queue through the Management API. | Yes |\n| `rabbitmq:doctor` | Run config, security, connection, Management API, and optional round-trip checks. | Yes |\n| `rabbitmq:consume-test` | Publish and consume a round-trip test message. | Yes, with a test queue. |\n| `rabbitmq:purge` | Purge a queue. | No |\n\n### `rabbitmq:doctor`\n\n```bash\nphp artisan rabbitmq:doctor\nphp artisan rabbitmq:doctor default --queue=laravel-rabbit.doctor\nphp artisan rabbitmq:doctor --skip-roundtrip\n```\n\nChecks:\n\n- connection configuration exists\n- security policy passes\n- `QUEUE_CONNECTION` is `rabbitmq`\n- Laravel queue driver is registered\n- AMQP channel can open\n- Management API is reachable when enabled\n- optional publish/consume round trip succeeds\n\n### `rabbitmq:management`\n\n```bash\nphp artisan rabbitmq:management\nphp artisan rabbitmq:management --queue=orders\nphp artisan rabbitmq:management --queues\nphp artisan rabbitmq:management --vhost=/\n```\n\n| Mode | Output |\n| --- | --- |\n| default | Cluster name, RabbitMQ version, object totals, and message totals. |\n| `--queue=orders` | Queue state, ready messages, reserved messages, total messages, consumers, memory, and idle time. |\n| `--queues` | Queue list with ready, reserved, total, consumers, and state. |\n\n### `rabbitmq:stats`\n\n```bash\nphp artisan rabbitmq:stats orders\n```\n\nWhen the Management API is enabled, this command shows real broker metrics. Without it, RabbitMQ's AMQP queue declaration only provides total ready depth, so reserved and delayed counts are not available.\n\n### Other Commands\n\n| Command | Example |\n| --- | --- |\n| Connectivity check | `php artisan rabbitmq:check default --queue=orders` |\n| Topology setup | `php artisan rabbitmq:setup default --queue=orders` |\n| Consume test | `php artisan rabbitmq:consume-test default --queue=healthcheck` |\n| Purge queue | `php artisan rabbitmq:purge orders --force` |\n\n## Low-Level AMQP Usage\n\nUse the facade when you need direct AMQP behavior outside Laravel's queue worker.\n\n### Publish Text\n\n```php\nuse Pushin\\LaravelRabbit\\Facades\\LaravelRabbit;\n\nLaravelRabbit::publish(\n    body: 'order created',\n    routingKey: 'orders.created',\n    exchange: 'events',\n);\n```\n\n### Publish JSON\n\n```php\nuse Illuminate\\Support\\Str;\nuse Pushin\\LaravelRabbit\\Facades\\LaravelRabbit;\n\nLaravelRabbit::publishJson(\n    payload: ['order_id' =\u003e 123],\n    routingKey: 'orders.created',\n    exchange: 'events',\n    properties: [\n        'correlation_id' =\u003e (string) Str::uuid(),\n        'headers' =\u003e [\n            'tenant' =\u003e 'pushin',\n        ],\n    ],\n);\n```\n\n### Consume Messages\n\n```php\nuse PhpAmqpLib\\Message\\AMQPMessage;\nuse Pushin\\LaravelRabbit\\Facades\\LaravelRabbit;\n\nLaravelRabbit::consume(function (AMQPMessage $message): void {\n    $payload = json_decode($message-\u003egetBody(), true, flags: JSON_THROW_ON_ERROR);\n\n    // Process the message.\n});\n```\n\nBy default, a message is acknowledged when the callback finishes without errors. If the callback returns `false`, the message is nacked.\n\n```php\nuse PhpAmqpLib\\Message\\AMQPMessage;\nuse Pushin\\LaravelRabbit\\Facades\\LaravelRabbit;\nuse Pushin\\LaravelRabbit\\ValueObjects\\ConsumerResult;\n\nLaravelRabbit::consume(function (AMQPMessage $message): ConsumerResult {\n    return ConsumerResult::nack(requeue: true);\n});\n```\n\n### Consume Options\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `tag` | `''` | Consumer tag. |\n| `no_ack` | `false` | When true, RabbitMQ auto-acknowledges deliveries. |\n| `exclusive` | `false` | Exclusive consumer. |\n| `wait_timeout` | `1.0` | Wait timeout per consume loop. |\n| `idle_timeout` | `null` | Stop after idle timeout. |\n| `max_messages` | `null` | Stop after consuming this many messages. |\n| `stop_when_empty` | `false` | Stop after the queue is empty. |\n| `ack_on_success` | `true` | Ack when callback succeeds. |\n| `nack_on_false` | `true` | Nack when callback returns `false`. |\n| `nack_on_false_requeue` | `false` | Requeue when callback returns `false`. |\n| `reject_on_exception` | `true` | Reject when callback throws. |\n| `reject_on_exception_requeue` | `false` | Requeue when callback throws. |\n\n```php\nLaravelRabbit::consume($callback, options: [\n    'tag' =\u003e 'orders-worker-1',\n    'wait_timeout' =\u003e 1.0,\n    'idle_timeout' =\u003e 30.0,\n    'max_messages' =\u003e 100,\n]);\n```\n\n### Get One Message\n\n```php\n$message = LaravelRabbit::get(queue: 'orders');\n\nif ($message !== null) {\n    // Process and manually acknowledge when noAck=false.\n    $message-\u003eack();\n}\n```\n\n### Use a Specific Connection\n\n```php\nLaravelRabbit::connection('analytics')-\u003epublishJson(\n    payload: ['event' =\u003e 'checkout'],\n    routingKey: 'analytics.checkout',\n);\n```\n\nFacade shortcut:\n\n```php\nLaravelRabbit::publishJson(\n    payload: ['event' =\u003e 'checkout'],\n    routingKey: 'analytics.checkout',\n    connection: 'analytics',\n);\n```\n\n## Topology\n\nThe package can automatically declare exchanges, queues, and bindings when a channel is opened.\n\n```php\n'topology' =\u003e [\n    'auto_declare' =\u003e true,\n    'exchanges' =\u003e [\n        'events' =\u003e [\n            'type' =\u003e 'topic',\n            'durable' =\u003e true,\n            'auto_delete' =\u003e false,\n        ],\n    ],\n    'queues' =\u003e [\n        'orders' =\u003e [\n            'durable' =\u003e true,\n            'arguments' =\u003e [\n                'x-dead-letter-exchange' =\u003e 'events.dlx',\n                'x-message-ttl' =\u003e 60000,\n            ],\n        ],\n    ],\n    'bindings' =\u003e [\n        [\n            'queue' =\u003e 'orders',\n            'exchange' =\u003e 'events',\n            'routing_key' =\u003e 'orders.*',\n        ],\n    ],\n],\n```\n\nManual declarations are also supported:\n\n```php\n$rabbit = LaravelRabbit::connection();\n\n$rabbit-\u003edeclareExchange('events', ['type' =\u003e 'topic', 'durable' =\u003e true]);\n$rabbit-\u003edeclareQueue('orders', ['durable' =\u003e true]);\n$rabbit-\u003ebindQueue('orders', 'events', 'orders.*');\n```\n\n## Production Options\n\n### Publisher Confirms\n\nPublisher confirms are enabled by default.\n\n```php\n'publisher_confirms' =\u003e [\n    'enabled' =\u003e true,\n    'wait' =\u003e true,\n    'timeout' =\u003e 5.0,\n    'wait_for_returns' =\u003e false,\n],\n```\n\nTo handle returned messages, publish with `mandatory=true` and register a return listener.\n\n```php\nuse PhpAmqpLib\\Message\\AMQPMessage;\n\nLaravelRabbit::connection()\n    -\u003eonReturned(function ($replyCode, $replyText, $exchange, $routingKey, AMQPMessage $message): void {\n        report(\"RabbitMQ returned message: {$replyCode} {$replyText}\");\n    })\n    -\u003epublish('payload', options: [\n        'mandatory' =\u003e true,\n        'wait_for_returns' =\u003e true,\n    ]);\n```\n\n### QoS / Prefetch\n\n```php\n'qos' =\u003e [\n    'enabled' =\u003e true,\n    'prefetch_size' =\u003e 0,\n    'prefetch_count' =\u003e 10,\n    'global' =\u003e false,\n],\n```\n\n```php\nLaravelRabbit::connection()-\u003eqos(prefetchCount: 25);\n```\n\n### Host Failover\n\n```php\n'connections' =\u003e [\n    'default' =\u003e [\n        'user' =\u003e env('RABBITMQ_USER'),\n        'password' =\u003e env('RABBITMQ_PASSWORD'),\n        'vhost' =\u003e '/',\n        'hosts' =\u003e [\n            ['host' =\u003e 'rabbit-a.internal', 'port' =\u003e 5671],\n            ['host' =\u003e 'rabbit-b.internal', 'port' =\u003e 5671],\n        ],\n        'ssl' =\u003e [\n            'enabled' =\u003e true,\n            'verify_peer' =\u003e true,\n            'verify_peer_name' =\u003e true,\n        ],\n        'reconnect' =\u003e [\n            'attempts' =\u003e 3,\n            'sleep_ms' =\u003e 250,\n            'multiplier' =\u003e 1.5,\n        ],\n    ],\n],\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eConnection options\u003c/summary\u003e\n\n| Option | Description |\n| --- | --- |\n| `host`, `port`, `vhost`, `user`, `password` | RabbitMQ connection target and credentials. |\n| `hosts` | Host list for failover. Host entries inherit root options and may override them. |\n| `connection_name` | Name shown in RabbitMQ connection metadata. |\n| `io_type` | `stream` or `socket`. |\n| `lazy` | Defer connection creation until first use. |\n| `insist` | AMQP insist flag. |\n| `login_method` | `AMQPLAIN`, `PLAIN`, or `EXTERNAL`. |\n| `login_response` | Optional login response. |\n| `locale` | AMQP locale, usually `en_US`. |\n| `connection_timeout` | TCP connection timeout. |\n| `read_timeout` | Socket read timeout. |\n| `write_timeout` | Socket write timeout. |\n| `channel_rpc_timeout` | Channel RPC timeout. |\n| `heartbeat` | RabbitMQ heartbeat interval. |\n| `keepalive` | TCP keepalive flag. |\n| `send_buffer_size` | Optional send buffer size. |\n| `dispatch_signals` | Whether php-amqplib dispatches signals. |\n| `protocol_strict_fields` | Strict AMQP field validation. |\n| `debug_packets` | Packet debug flag. |\n\n\u003c/details\u003e\n\n## Security\n\n### Queue Payload Signing\n\nQueue payload signing is an optional defense against job injection. When enabled, the driver adds an HMAC signature to every Laravel queue payload it publishes. During `queue:work`, messages without a valid signature are rejected before Laravel attempts to execute the job.\n\n```dotenv\nRABBITMQ_QUEUE_SIGN_PAYLOADS=true\nRABBITMQ_QUEUE_SIGNING_KEY=\"${APP_KEY}\"\nRABBITMQ_QUEUE_INVALID_SIGNATURE_REQUEUE=false\n```\n\n| Env | Default | Description |\n| --- | --- | --- |\n| `RABBITMQ_QUEUE_SIGN_PAYLOADS` | `false` | Adds an HMAC signature to new queue payloads. |\n| `RABBITMQ_QUEUE_VERIFY_PAYLOAD_SIGNATURES` | same as `RABBITMQ_QUEUE_SIGN_PAYLOADS` | Verifies signatures before returning a job to Laravel's worker. |\n| `RABBITMQ_QUEUE_SIGNING_KEY` | `APP_KEY` | Secret key used for HMAC signing. Use the same value across all app instances that publish or consume these jobs. |\n| `RABBITMQ_QUEUE_INVALID_SIGNATURE_REQUEUE` | `false` | When false, invalid messages are nacked without requeue to avoid poison-message loops. |\n\n\u003e [!NOTE]\n\u003e Payload signing does not replace broker security. Keep RabbitMQ credentials scoped per app, restrict vhost permissions, use TLS outside local development, and do not allow untrusted systems to publish into Laravel worker queues.\n\n### TLS\n\n```dotenv\nRABBITMQ_SSL=true\nRABBITMQ_PORT=5671\nRABBITMQ_SSL_CAFILE=/etc/ssl/certs/ca.pem\nRABBITMQ_SSL_VERIFY_PEER=true\nRABBITMQ_SSL_VERIFY_PEER_NAME=true\n```\n\n```php\n'ssl' =\u003e [\n    'enabled' =\u003e true,\n    'cafile' =\u003e '/path/ca.pem',\n    'capath' =\u003e null,\n    'local_cert' =\u003e '/path/client.pem',\n    'local_pk' =\u003e '/path/client.key',\n    'passphrase' =\u003e env('RABBITMQ_SSL_PASSPHRASE'),\n    'verify_peer' =\u003e true,\n    'verify_peer_name' =\u003e true,\n    'ciphers' =\u003e null,\n    'security_level' =\u003e null,\n    'crypto_method' =\u003e 'STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT',\n],\n```\n\nFor security, `verify_peer=false` or `verify_peer_name=false` throws an exception unless `security.allow_insecure_tls=true`.\n\n### Security Guards\n\n```php\n'security' =\u003e [\n    'require_tls' =\u003e false,\n    'allow_insecure_tls' =\u003e false,\n    'enforce_tls_peer_verification' =\u003e true,\n    'forbid_guest_on_remote_hosts' =\u003e true,\n    'max_message_size' =\u003e null,\n],\n```\n\n| Guard | Default | Effect |\n| --- | --- | --- |\n| `require_tls` | `false` | Rejects non-TLS AMQP connections when enabled. |\n| `allow_insecure_tls` | `false` | Required before disabling TLS peer verification. |\n| `enforce_tls_peer_verification` | `true` | Requires peer and peer-name verification for TLS. |\n| `forbid_guest_on_remote_hosts` | `true` | Rejects the `guest` user outside local hosts. |\n| `max_message_size` | `null` | Rejects publishes larger than the configured byte limit. |\n\nRecommendations:\n\n- Use TLS outside local development.\n- Do not use the `guest` user on remote hosts.\n- Keep `verify_peer` and `verify_peer_name` enabled.\n- Configure `max_message_size` when your application has a known payload limit.\n- Prefer publisher confirms for important flows.\n\n## Message Properties\n\nAccepted properties follow `AMQPMessage`.\n\n| Property | Description |\n| --- | --- |\n| `content_type` | MIME type of the payload. |\n| `content_encoding` | Payload encoding. |\n| `headers` / `application_headers` | Application headers. |\n| `delivery_mode` | Use `2` for persistent messages. |\n| `priority` | Message priority. |\n| `correlation_id` | Correlation id for tracing or RPC. |\n| `reply_to` | Reply queue. |\n| `expiration` | Per-message TTL in milliseconds as a string. |\n| `message_id` | Message id. |\n| `timestamp` | Message timestamp. |\n| `type` | Application message type. |\n| `user_id` | User id. |\n| `app_id` | Application id. |\n| `cluster_id` | Cluster id. |\n\n```php\nLaravelRabbit::publishJson(\n    ['order_id' =\u003e 123],\n    properties: [\n        'delivery_mode' =\u003e 2,\n        'expiration' =\u003e '60000',\n        'priority' =\u003e 5,\n        'headers' =\u003e [\n            'source' =\u003e 'checkout',\n        ],\n    ],\n);\n```\n\n## Testing\n\n```bash\ncomposer test\ncomposer test:unit\ncomposer test:feature\n```\n\n| Test area | Covered |\n| --- | --- |\n| Publishing | Text, JSON, properties, confirms, and routing. |\n| Consuming | Callback flow, ack, nack, reject, timeout, and round-trip tests. |\n| Laravel queue | Dispatch, `onQueue`, delayed jobs, release, clear, and worker integration. |\n| Management API | Metrics mapping, command output, TLS policy, and remote `guest` guard. |\n| Security | Queue payload signing, tamper rejection, insecure TLS, remote `guest`, config sanitization, and max message size. |\n| Topology | Exchanges, queues, bindings, queue arguments, and AMQP table conversion. |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpush-in%2Flaravel-rabbit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpush-in%2Flaravel-rabbit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpush-in%2Flaravel-rabbit/lists"}