NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #2665 most downloaded on Packagist
AMQP wrapper for Laravel and Lumen to publish and consume messages
Last release 4 months ago
02 Jun 2026
Ships unpredictably
gaps range from 2 weeks to 2.8 years
Rarely documented
notes for 6 of 28 stable releases
Nothing withdrawn
no release was ever pulled
10 years old
28 releases · first in 2016
Full suite passes on PHP 7.3 through 8.5. Deprecation warnings on PHP 8.4+ continue to come exclusively from the vendored Mockery library and predate…
A purely additive patch on top of 3.4.0 that introduces two new
capability layers — a gRPC-lite typed RPC stack and the
Laravel Messaging Platform (service discovery, sagas-as-a-facade,
typed-message dispatch, dead-letter management, declarative retry,
monitoring dashboard, causation IDs, MessageStore, and an async
Laravel-event bridge).
No migration required. Every new feature is opt-in; existing
publish/consume code, handler signatures, configuration layouts, and
the public surface from 3.4.0 continue to work unchanged.
#[Retry] attributes).^9.6 on PHP 7.3/7.4; ^10.5|^11.5|^12.0 on PHP 8.0+.src/ parses as PHP 7.3 — verified byscripts/check-php73-compat.php (curated) andscripts/check-php73-compat-all-src.php (entire tree) usingnikic/php-parser.A typed, service-oriented RPC layer that feels like gRPC but rides on
RabbitMQ. Built as a thin abstraction over the existing
Request/Consumer::reply() RPC primitive — no new dependencies, no
new transports.
Service contract & DTOs
Bschmitt\Amqp\Rpc\RpcService — abstract contract withqueue(), methods() (mapping request DTO → handler method), andname() / exchange() / routingKey() overrides.Bschmitt\Amqp\Rpc\RpcRequest / Bschmitt\Amqp\Rpc\RpcResponsemake(array $payload) factory built on the existingTypedMessage reflection hydration.RpcRequest::responseClass() lets a request declare its typedRpc::call() hydrates the response automatically.Rpc facade & dispatcher
Bschmitt\Amqp\Rpc\RpcDispatcher coordinates symmetriccall() / serve() / register() flow with x-rpc-service andx-rpc-request headers for routing and tracing.Bschmitt\Amqp\Facades\Rpc auto-registered via composer.jsonRpc::call(UserService::class, GetUserRequest::make([...]))).Amqp::rpcDispatcher() accessor for non-facade contexts.Rpc::register(UserService::class, UserServiceHandler::class)->serve(UserService::class)).Error & timeout typing
Bschmitt\Amqp\Rpc\RpcException — remote-handler errors carryBschmitt\Amqp\Rpc\RpcTimeoutException — distinct type so callers_rpc_error envelope, and surfaced to the client as the typedConfigurable per-call
Rpc::defaultTimeout($seconds).timeout and extra publish properties:Rpc::call(UserService::class, GetUserRequest::make([...]), 5, ['exchange' => 'rpc.svc']).Higher-level building blocks that turn the package from "an AMQP
client" into a Laravel-first microservice toolkit. Every item below is
purely additive and ships with unit-test coverage.
Service discovery (Rpc::service('payments'))
Bschmitt\Amqp\Rpc\ServiceRegistry — register short names → serviceRpc::services()->register('payments', PaymentsService::class)).autodiscover([...]) honours an opt-in public static function alias()RpcService subclasses.Bschmitt\Amqp\Rpc\ServiceCaller — fluent caller with timeout()withProperties() chaining;Rpc::service($alias|$fqcn)->call($request).Saga facade + compensate() syntax
Saga::make() static factory and a new top-level Saga facadecomposer.json).->step('reserve', $reserve)->compensate($release).step($name, $action, $compensation) form still works.Message contract dispatch
TypedMessage::make(array $payload) andTypedMessage::dispatch(array $payload, array $properties = [])TypedMessage::dispatchLater(array $payload, int $delayMs) mirrorsAmqp singleton from the Laravel container; throws aRuntimeException when called outside Laravel.Dead-letter management (Amqp::deadLetters())
Bschmitt\Amqp\Support\DeadLetterManager fluent API:for($queue)->count() / messages($limit) / replayTo($target, $limit)purge().#[Retry] attribute + RetryStrategy
Bschmitt\Amqp\Attributes\Retry(attempts, strategy, delayMs, maxDelayMs, jitter) with PHP 8+ attribute target.Bschmitt\Amqp\Support\RetryStrategy::{FIXED|EXPONENTIAL|LINEAR|NONE}RetryPolicy::fromAttribute($class, $method = null) reflectionRetryPolicy from the attribute.Monitoring dashboard + amqp:monitor
Bschmitt\Amqp\Support\MonitoringDashboard aggregatesMetricsCollector (in-process counters) and Management API queueAmqp::dashboard($queues)->snapshot() returns['process' => ..., 'queues' => ..., 'overview' => ..., 'generated' => ...].php artisan amqp:monitor --queue=orders [--queue=...] [--json] [--connection=]Bschmitt\Amqp\Console\Commands\AmqpMonitorCommand)Causation ID propagation
CorrelationContext now tracks a causation id alongside thesetCausation() / getCausation() and a newCAUSATION_HEADER constant.CorrelationContext::inheritFromMessage($incoming) captures themessage_id as the causation id of anything publishedapplyToPublishProperties() adds an x-causation-id headerMessageStore (Bschmitt\Amqp\Contracts\MessageStoreInterface)
append() / find() / all($filters) / count($filters) / purge().Bschmitt\Amqp\Support\InMemoryMessageStore defaultAmqp::setMessageStore($store) / Amqp::messageStore() accessors;Async Laravel events (ShouldPublishToAmqpInterface)
event(new OrderCreated(...)) becomesBschmitt\Amqp\Events\AmqpEventListener wildcard listeneramqpRouting() / amqpPayload() / amqpExchange()amqp.broadcast_laravel_events => true.Bschmitt\Amqp\Rpc\{RpcDispatcher, RpcService, RpcRequest, RpcResponse, RpcMessage, RpcException, RpcTimeoutException, ServiceCaller, ServiceRegistry}Bschmitt\Amqp\Facades\{Rpc, Saga}Bschmitt\Amqp\Attributes\RetryBschmitt\Amqp\Support\{RetryStrategy, DeadLetterManager, InMemoryMessageStore, MonitoringDashboard}Bschmitt\Amqp\Contracts\{MessageStoreInterface, ShouldPublishToAmqpInterface}Bschmitt\Amqp\Events\AmqpEventListenerBschmitt\Amqp\Console\Commands\AmqpMonitorCommandAmqp facade methods: rpcDispatcher(), deadLetters(),dashboard($queues), setMessageStore(), messageStore().Bschmitt\Amqp\Support\{Saga, TypedMessage, RetryPolicy, CorrelationContext},Bschmitt\Amqp\Rpc\RpcDispatcher, Bschmitt\Amqp\Providers\AmqpServiceProvider.docs/content/grpc-lite-rpc.mddocs/content/messaging-platform.mddocs/app.js) and feature cardsdocs/index.html).README.md gains a "gRPC-lite RPC" section and atest/Unit/:Rpc/RpcDispatcherTest, Rpc/RpcMessageTest,Rpc/ServiceRegistryTest, Rpc/ServiceCallerTest,SagaFacadeTest, DeadLetterManagerTest,InMemoryMessageStoreTest, MonitoringDashboardTest,RetryAttributeTest, CausationContextTest,AmqpEventListenerTest.test/Support/Fixtures/Rpc/:UserService, UserServiceHandler, GetUserRequest,GetUserResponse, CreateUserRequest.No migration required. Everything below is opt-in:
Rpc and Saga facades are auto-registered viacomposer.json aliases — they only become visible to user code whenTypedMessage::make() / dispatch() / dispatchLater() are newDeadLetterManager, MonitoringDashboard, and MessageStore aresetMessageStore(...) is invoked.#[Retry] attribute is read only when application code asksRetryPolicy::fromAttribute(...); existing RetryPolicyCorrelationContext keeps its previous API; the newsetCausation() / getCausation() / CAUSATION_HEADER constantsx-causation-id header only appear when callers activelyinheritFromMessage()).amqp.broadcast_laravel_events is set to true in config/amqp.php.Full Changelog: v3.4.0...v3.4.1
One column per quarter.
Full suite passes on PHP 8.3 and 8.4; deprecation warnings on 8.4 come exclusively from the vendored Mockery library and predate this release.
A consolidated release that lands twenty features from the roadmap across
retry/DLQ, delayed/typed/schema messaging, production infrastructure,
workflows/testing, and scale/interop -- all fully backwards-compatible and
verified on PHP 7.3 through 8.5.
No migration required. Every new feature is opt-in; existing publish/consume
code, handler signatures, and config layouts continue to work unchanged.
^9.6 on PHP 7.3/7.4; ^10.5|^11.5|^12.0 on PHP 8.0+scripts/check-php73-compat.php (curated) andscripts/check-php73-compat-all-src.php (entire src/) usingnikic/php-parser — every file under src/ parses as PHP 7.3.Advanced retry & dead-letter abstractions
Bschmitt\Amqp\Support\RetryPolicy value object withfixed() / exponential() / immediate() / none() factories andmaxDelayMs cap + jitterMs.DeadLetterTopology builder generates property bags for the work{queue}.retry.{ms}).RetryHandler decorator wraps any callable with the fullx-retry-attempt,x-first-failed-at, and x-last-error headers).Amqp::declareRetryTopology(), retryHandler(),consumeWithRetry(), topology().amqp:work gains --retry, --retry-backoff, --retry-delay,--retry-multiplier, --retry-max-delay, --retry-jitter,--dlq, and --declare-topology.Delayed messaging & publisher backoff
Bschmitt\Amqp\Support\DelayedPublisher with two strategies:ttl (default, TTL+DLX per-delay queue — works on stock RabbitMQ)plugin (rabbitmq-delayed-message-exchange).Amqp::publishLater(), publishTypedLater(),delayedPublisher().PublishBackoff wraps any publish closure with a RetryPolicy,Amqp::withPublishBackoff().amqp:publish gains --delay-ms and --delay-strategy=ttl|plugin.Typed message contracts & DTO serialization
Bschmitt\Amqp\Contracts\MessageContractInterface and theTypedMessage base class (reflection-driven defaults plusroutingKey(), exchange(), schema() hooks).MessageSerializerInterface strategy; default isJsonMessageSerializer (JSON_THROW_ON_ERROR, unicode/slash-safe).Amqp::publishTyped(), publishTypedLater(), consumeTyped(),setSerializer(), getSerializer().amqp:work --contract= deserializes inbound bodies and passes thenull).JSON Schema validation for messages
Bschmitt\Amqp\Support\SchemaValidatorrequired, properties,additionalProperties, string/number/array constraints, enum,const, oneOf/anyOf/allOf/not, common formats).SchemaValidationException carries errors() with JSON-pointerschema().amqp:work --validate-schema enforces in long-running workers.Exchange & topology builders
ExchangeTopology fluent builder for exchange + multi-queue bindings.Amqp::declareExchangeTopology(), exchangeTopology() shortcut.Quorum & priority queue profiles
QueueProfile presets: classic(), quorum(), priority(),quorumWithPriority() with mergeInto() for property bags.Auto reconnect & heartbeat monitoring
ResilientConnectionManager decorator with connect retries andAmqp::resilientConnection() factory helper.Connection pooling & persistent channels
ConnectionPool singleton via Amqp::connectionPool() withDistributed tracing (W3C, OTel-ready)
TraceContext, TracePropagatorInterface, W3cTracePropagator,NullTracePropagator, CallbackTracePropagator for APM bridges.propagate_trace flag on publish/consume; Amqp::setTracePropagator().Correlation ID propagation
CorrelationContext with propagate_correlation integration onconsumeWithLifecycle().Consumer lifecycle management
ConsumerLifecycle hooks (starting/stopping/message/error), signalAmqp::consumeWithLifecycle().SAGA workflow helpers
Saga builder with step($name, $action, $compensation) andSagaResult reports succeeded/failed status, per-step results, theAmqp::saga($name) shortcut.Laravel events
Bschmitt\Amqp\Events\: MessagePublishing,MessagePublished, MessageReceived, MessageHandled,MessageFailed.Illuminate\Support\Facades\Event when available;EventDispatcher for non-Laravel contexts.Consume middleware pipeline
ConsumeMiddlewareInterface and ConsumePipeline.Amqp::consumeWithMiddleware($queue, $handler, $middlewares, $properties).Fake AMQP test driver
Bschmitt\Amqp\Testing\FakeAmqp extends Amqp with nullassertPublished(), assertNotPublished(),assertNothingPublished(), assertPublishedCount().Amqp::fake() swaps the bound singleton (or returns a standalone fakePublisher confirms & async publishing
AsyncPublisher with persistent channel, confirm_select,onAck() / onNack() callbacks, and flush() / stats().Amqp::asyncPublisher($properties) shortcut.Publisher confirms (publisher_confirms,wait_for_confirms, waitForConfirms()).RPC abstraction helpers
RpcClient + RpcCallResult with JSON mode and configurableRpcServer auto-reply consumer wrapper.Amqp::rpcClient(), rpcServer().Cross-service / polyglot messaging
InteropEnvelope / InteropMessage with standard headersx-message-type, x-schema-version, x-source-service).Amqp::publishInterop(), consumeInterop().Enhanced observability & queue metrics
MetricsCollector with Amqp::metrics() (auto-increment onQueueMetrics normalized view of Management API stats.Amqp::queueMetrics(), getQueueStats() alias.High-performance worker optimizations
WorkerOptions presets (throughput, lowLatency).HighPerformanceWorker, Amqp::consumeOptimized().amqp:work --optimized (prefetch=50 when not overridden).docs/content/delayed-messaging.mddocs/content/typed-messaging.mddocs/content/schema-validation.mddocs/content/production-features.mddocs/content/workflow-events-testing.mddocs/content/scale-and-interop.mddocs/content/advanced.md, publishing.md, consuming.md,artisan-commands.md, best-practices.md, faq.md,getting-started.md, guide.md, USER_MANUAL.md, README.md.docs/index.html; newNo migration required. All new features are opt-in:
null when --contract is not used.MessageHandlerInterface::handle() gains an optional $typed = nullMessageSerializerInterface is lazily resolved asJsonMessageSerializer — existing publish/consume calls that send rawA consolidated release that lands the original twenty roadmap features plus nine "messaging-platform" additions (service discovery, sagas-as-a-facade, typed-message dispatch, DLQ management, retry attribute, monitoring dashboard, causation IDs, MessageStore, async Laravel events) — all fully backwards-compatible and verified on PHP 7.3 through 8.5.
No migration required. Every new feature is opt-in; existing publish/consume code, handler signatures, and config layouts continue to work unchanged.
^9.6 on PHP 7.3/7.4; ^10.5|^11.5|^12.0 on PHP 8.0+scripts/check-php73-compat.php (curated) and
scripts/check-php73-compat-all-src.php (entire src/) using
nikic/php-parser — every file under src/ parses as PHP 7.3.Advanced retry & dead-letter abstractions
Bschmitt\Amqp\Support\RetryPolicy value object with
fixed() / exponential() / immediate() / none() factories and
configurable maxDelayMs cap + jitterMs.DeadLetterTopology builder generates property bags for the work
queue, DLQ, and per-delay retry queues ({queue}.retry.{ms}).RetryHandler decorator wraps any callable with the full
republish-or-reject pipeline (tracks x-retry-attempt,
x-first-failed-at, and x-last-error headers).Amqp::declareRetryTopology(), retryHandler(),
consumeWithRetry(), topology().amqp:work gains --retry, --retry-backoff, --retry-delay,
--retry-multiplier, --retry-max-delay, --retry-jitter,
--dlq, and --declare-topology.Delayed messaging & publisher backoff
Bschmitt\Amqp\Support\DelayedPublisher with two strategies:
ttl (default, TTL+DLX per-delay queue — works on stock RabbitMQ)
and plugin (rabbitmq-delayed-message-exchange).Amqp::publishLater(), publishTypedLater(),
delayedPublisher().PublishBackoff wraps any publish closure with a RetryPolicy,
exposed via Amqp::withPublishBackoff().amqp:publish gains --delay-ms and --delay-strategy=ttl|plugin.Typed message contracts & DTO serialization
Bschmitt\Amqp\Contracts\MessageContractInterface and the
optional TypedMessage base class (reflection-driven defaults plus
routingKey(), exchange(), schema() hooks).MessageSerializerInterface strategy; default is
JsonMessageSerializer (JSON_THROW_ON_ERROR, unicode/slash-safe).Amqp::publishTyped(), publishTypedLater(), consumeTyped(),
setSerializer(), getSerializer().amqp:work --contract= deserializes inbound bodies and passes the
DTO as a third handler argument (the existing two-argument signature
keeps working — the new arg defaults to null).JSON Schema validation for messages
Bschmitt\Amqp\Support\SchemaValidator
implementing a Draft 7 subset (types, required, properties,
additionalProperties, string/number/array constraints, enum,
const, oneOf/anyOf/allOf/not, common formats).SchemaValidationException carries errors() with JSON-pointer
paths.schema().amqp:work --validate-schema enforces in long-running workers.Exchange & topology builders
ExchangeTopology fluent builder for exchange + multi-queue bindings.Amqp::declareExchangeTopology(), exchangeTopology() shortcut.Quorum & priority queue profiles
QueueProfile presets: classic(), quorum(), priority(),
quorumWithPriority() with mergeInto() for property bags.Auto reconnect & heartbeat monitoring
ResilientConnectionManager decorator with connect retries and
heartbeat staleness detection.Amqp::resilientConnection() factory helper.Connection pooling & persistent channels
ConnectionPool singleton via Amqp::connectionPool() with
persistent key support and optional resilient wrapping.Distributed tracing (W3C, OTel-ready)
TraceContext, TracePropagatorInterface, W3cTracePropagator,
NullTracePropagator, CallbackTracePropagator for APM bridges.propagate_trace flag on publish/consume; Amqp::setTracePropagator().Correlation ID propagation
CorrelationContext with propagate_correlation integration on
publish and consumeWithLifecycle().Consumer lifecycle management
ConsumerLifecycle hooks (starting/stopping/message/error), signal
handlers, and Amqp::consumeWithLifecycle().SAGA workflow helpers
Saga builder with step($name, $action, $compensation) and
reverse-order compensations on failure.SagaResult reports succeeded/failed status, per-step results, the
failing step, exception, and which steps were compensated.Amqp::saga($name) shortcut.Laravel events
Bschmitt\Amqp\Events\: MessagePublishing,
MessagePublished, MessageReceived, MessageHandled,
MessageFailed.Illuminate\Support\Facades\Event when available;
fallback singleton EventDispatcher for non-Laravel contexts.Consume middleware pipeline
ConsumeMiddlewareInterface and ConsumePipeline.Amqp::consumeWithMiddleware($queue, $handler, $middlewares, $properties).Fake AMQP test driver
Bschmitt\Amqp\Testing\FakeAmqp extends Amqp with null
publisher/consumer/factory stubs.assertPublished(), assertNotPublished(),
assertNothingPublished(), assertPublishedCount().Amqp::fake() swaps the bound singleton (or returns a standalone fake
when no Laravel app is active).Publisher confirms & async publishing
AsyncPublisher with persistent channel, confirm_select,
onAck() / onNack() callbacks, and flush() / stats().Amqp::asyncPublisher($properties) shortcut.Publisher confirms (publisher_confirms,
wait_for_confirms, waitForConfirms()).RPC abstraction helpers
RpcClient + RpcCallResult with JSON mode and configurable
timeouts.RpcServer auto-reply consumer wrapper.Amqp::rpcClient(), rpcServer().Cross-service / polyglot messaging
InteropEnvelope / InteropMessage with standard headers
(x-message-type, x-schema-version, x-source-service).Amqp::publishInterop(), consumeInterop().Enhanced observability & queue metrics
MetricsCollector with Amqp::metrics() (auto-increment on
publish / consume).QueueMetrics normalized view of Management API stats.Amqp::queueMetrics(), getQueueStats() alias.High-performance worker optimizations
WorkerOptions presets (throughput, lowLatency).HighPerformanceWorker, Amqp::consumeOptimized().amqp:work --optimized (prefetch=50 when not overridden).RpcService contract (queue(), methods(), optional
name() / exchange() / routingKey()).RpcRequest / RpcResponse DTOs with make() factory built on
TypedMessage reflection.RpcDispatcher coordinates symmetric call() / serve() /
register() flow with x-rpc-service and x-rpc-request
headers for routing and tracing.Rpc facade auto-registered (Rpc::call(UserService::class, GetUserRequest::make([...]))).RpcException (remote handler errors carry original class name) and
RpcTimeoutException.Amqp::rpcDispatcher() accessor; container-resolvable handler FQCNs.docs/content/delayed-messaging.mddocs/content/typed-messaging.mddocs/content/schema-validation.mddocs/content/production-features.mddocs/content/workflow-events-testing.mddocs/content/scale-and-interop.mddocs/content/grpc-lite-rpc.mddocs/content/advanced.md, publishing.md, consuming.md,
artisan-commands.md, best-practices.md, faq.md,
getting-started.md, guide.md, USER_MANUAL.md, README.md.docs/index.html; new
"Typed Messages" quick-start tab on the home page.The package now ships the building blocks of a full Laravel-first microservice toolkit alongside the v3.4 core. Every item below is purely additive and ships with unit-test coverage.
Service Discovery (Rpc::service('payments'))
Bschmitt\Amqp\Rpc\ServiceRegistry — register short names → service
FQCNs (Rpc::services()->register('payments', PaymentsService::class)).autodiscover() honours an opt-in static alias() method on
RpcService subclasses.Bschmitt\Amqp\Rpc\ServiceCaller — fluent caller with timeout() and
withProperties() chaining; Rpc::service($alias|$fqcn)->call($req).Saga facade + compensate() syntax
Saga::make() static factory and a new top-level Saga facade.->step('reserve', $reserve)->compensate($release).step($name, $action, $comp) form
still works.Message contract dispatch
TypedMessage::make(array $payload) and TypedMessage::dispatch(array $payload, array $properties = []) static helpers.TypedMessage::dispatchLater(array $payload, int $delayMs) mirrors the
delayed publisher.Amqp singleton from the Laravel container; throws a
clear RuntimeException when called outside Laravel.Dead-letter management (Amqp::deadLetters())
Bschmitt\Amqp\Support\DeadLetterManager fluent API:
for($queue)->count()/messages()/replayTo($target)/purge().#[Retry] attribute + RetryStrategy
Bschmitt\Amqp\Attributes\Retry(attempts, strategy, delayMs, maxDelayMs, jitter) with PHP 8+ attribute target.Bschmitt\Amqp\Support\RetryStrategy::{FIXED|EXPONENTIAL|LINEAR|NONE}
string constants (PHP 7.3-safe).RetryPolicy::fromAttribute($class, $method = null) reflection
helper builds an existing RetryPolicy from the attribute.Monitoring dashboard + amqp:monitor
Bschmitt\Amqp\Support\MonitoringDashboard aggregates
MetricsCollector (in-process) + Management API queue stats into a
single JSON-safe snapshot.Amqp::dashboard($queues)->snapshot() returns
['process' => ..., 'queues' => ..., 'overview' => ..., 'generated' => ...].php artisan amqp:monitor --queue=orders [--json] [--connection=]
Artisan command for ops/CI.Causation ID propagation
CorrelationContext now also tracks a causation id with
setCausation() / getCausation() and CAUSATION_HEADER.inheritFromMessage() captures the inbound message_id as the
causation id of anything published next.applyToPublishProperties() adds an x-causation-id header alongside
the existing correlation headers.MessageStore (Bschmitt\Amqp\Contracts\MessageStoreInterface)
append() / find() / all() / count() / purge().Bschmitt\Amqp\Support\InMemoryMessageStore default implementation.Amqp::setMessageStore() / messageStore() accessors; publish and
consume both auto-record when a store is attached.Async Laravel events (ShouldPublishToAmqpInterface)
Bschmitt\Amqp\Events\AmqpEventListener wildcard listener handles
routing, payload, and exchange resolution (with overridable
amqpRouting() / amqpPayload() / amqpExchange() hooks).Saga facade alias auto-registered via composer.json.amqp.broadcast_laravel_events => true.No migration required. All new features are opt-in:
null when --contract is not used.MessageHandlerInterface::handle() gains an optional $typed = null
parameter; implementations written against the old signature continue
to work because the new argument has a default value.MessageSerializerInterface is lazily resolved as
JsonMessageSerializer — existing publish/consume calls that send raw
bodies are unaffected.null by default — no recording happens unless you call
Amqp::setMessageStore(...).amqp.broadcast_laravel_events is set to true.ServiceRegistryTest, ServiceCallerTest,
SagaFacadeTest, DeadLetterManagerTest, InMemoryMessageStoreTest,
MonitoringDashboardTest, RetryAttributeTest, CausationContextTest,
AmqpEventListenerTest.Added explicit ? to nullable constructor parameters in ConsumerFactory , PublisherFactory , Consumer , and Publisher (avoids deprecation warnings on P…
This release broadens framework and PHP compatibility, improves configuration resolution, and expands CI coverage.
composer.json: ^7.3|^8.0)^8.0.2; CI/local installs use platform.php 8.0.2 (see scripts/ci-platform-php.sh)^9.6 on PHP 7.3/7.4; ^10.5|^11.5|^12.0 on PHP 8.0+ (resolved automatically by Composer)Configuration layouts
ConfigurationProvider accepts current use/properties, legacy default/connections, and flat single-connection configs.CI and local testing
scripts/ci-platform-php.sh and scripts/ci-composer-install.sh for correct Composer platform constraints.test-ci.sh for running the CI matrix locally.PHP 8.4+ and 8.5 compatibility fixes contributed by @dlpro in PR #136 (merged May 18, 2026):
PHP 8.4+ implicitly nullable parameters
? to nullable constructor parameters in ConsumerFactory, PublisherFactory, Consumer, and Publisher (avoids deprecation warnings on PHP 8.4 and fatal errors in PHP 9).DeadLetterExchangeIntegrationTest::createConfig().PHP 8.5 deprecations
curl_close() from ManagementApiClient (no-op since PHP 8.0, removed in PHP 8.5).ReflectionProperty::setAccessible() calls in unit/integration tests (deprecated in PHP 8.5; no-op since PHP 8.1).ReflectionTestTrait still calls setAccessible(true) on PHP 7.3/7.4 where reflection access requires it.No migration required. Existing config/amqp.php layouts continue to work.
This release includes Laravel 13 readiness updates, RPC reliability fixes, CI modernization, and a major documentation portal refresh.
This release includes Laravel 13 readiness updates, RPC reliability fixes, CI modernization, and a major documentation portal refresh.
10.x, 11.x, 12.x, and 13.x.Consumer::reply().correlation_id as a proper AMQP message property.CONTRIBUTING.md guidance.10.x, 11.x, 12.x, 13.x3.x (tested with rabbitmq:3-management)3.2.0) due to cumulative feature/documentation expansion plus fixes.Solves #127 , #128 Issues - Remove Amqp, Consumer, and Publisher classes; update integration test… by @zfhassaan in #129
Full Changelog: v3.1.0...v3.1.1
This patch release fixes critical issues that caused fatal errors and prepares the package for future php-amqplib versions.
Fixed #127: Removed Duplicate Class Files
src/Amqp.php, src/Consumer.php, src/Publisher.php)src/Core/ directory per PSR-4 standardsFixed #128: Replaced Deprecated AMQPSSLConnection
src/Core/Request.php to use AMQPConnectionFactory and AMQPConnectionConfigsrc/Managers/ConnectionManager.php to use new APIssl_options to new setSsl* methods (setSslCaCert, setSslCert, setSslKey, etc.)connect_options to new timeout/heartbeat/keepalive methodsFixed Test Errors: Added Null Checks in tearDown() Methods
testQueueName, alternateQueue, dlxQueue, etc.ManagementApiIntegrationTest deletePolicy() null checkNo migration required. This is a bug fix release that maintains full backward compatibility.
This release introduces significant new features, improvements, and bug fixes to the Laravel AMQP package. The package now provides comprehensive supp
This release introduces significant new features, improvements, and bug fixes to the Laravel AMQP package. The package now provides comprehensive support for RabbitMQ management operations, RPC patterns, message properties, and enhanced testing capabilities.
The package now includes built-in support for RPC patterns, making it easy to implement request-response communication between services.
$amqp->rpc() - Make RPC calls with automatic correlation ID and reply queue management
$amqp = app('Amqp');
$response = $amqp->rpc('rpc-queue', 'request-data', [], 30);Consumer::reply() - Send RPC responses from consumer callbacks
$amqp = app('Amqp');
$amqp->consume('rpc-queue', function ($message, $resolver) {
$result = processRequest($message->body);
$resolver->reply($message, $result);
$resolver->acknowledge($message);
});$amqp->listen() - Convenience method to auto-create queues and bind to multiple routing keys
$amqp = app('Amqp');
$amqp->listen(['key1', 'key2'], function ($message, $resolver) {
// Handle message
});Direct programmatic control over RabbitMQ queues and exchanges.
$amqp->queueUnbind() - Unbind a queue from an exchange$amqp->exchangeUnbind() - Unbind an exchange from another exchange$amqp->queuePurge() - Remove all messages from a queue$amqp->queueDelete() - Delete a queue$amqp->exchangeDelete() - Delete an exchange// Get Amqp instance
$amqp = app('Amqp');
// Purge all messages from a queue
$amqp->queuePurge('my-queue', ['queue' => 'my-queue']);
// Delete a queue
$amqp->queueDelete('my-queue', ['queue' => 'my-queue']);
// Unbind a queue from an exchange
$amqp->queueUnbind('my-queue', 'my-exchange', 'routing-key', [
'queue' => 'my-queue',
'exchange' => 'my-exchange'
]);Full integration with RabbitMQ's Management HTTP API for monitoring and statistics.
Amqp::getQueueStats() - Get queue statistics (message count, consumer count, etc.)Amqp::getConnections() - List all active connectionsAmqp::getChannels() - List all active channelsAmqp::getNodes() - Get cluster node informationAmqp::getPolicies() - List all policiesAmqp::createPolicy() - Create a new policyAmqp::updatePolicy() - Update an existing policyAmqp::deletePolicy() - Delete a policyAmqp::listFeatureFlags() - List all feature flagsAmqp::getFeatureFlag() - Get status of a specific feature flagAdd to your config/amqp.php:
'management_api_url' => 'http://localhost:15672',
'management_api_user' => 'guest',
'management_api_password' => 'guest',// Get Amqp instance
$amqp = app('Amqp');
// Get queue statistics
$stats = $amqp->getQueueStats('my-queue', '/');
// Returns: ['messages' => 10, 'consumers' => 2, ...]
// List all connections
$connections = $amqp->getConnections();
// Create a policy
$amqp->createPolicy('my-policy', '/', [
'pattern' => '^my-queue$',
'definition' => ['max-length' => 1000]
]);Programmatic management of RabbitMQ policies for queue and exchange configuration.
Query RabbitMQ feature flags to determine available capabilities.
Amqp::listFeatureFlags() - Get all feature flags and their statusAmqp::getFeatureFlag() - Check if a specific feature flag is enabledFull support for standard AMQP message properties.
// Get Amqp instance
$amqp = app('Amqp');
// Publish with message properties (using dynamic call)
$amqp->publish('routing-key', 'message', [
'priority' => 10,
'correlation_id' => 'unique-id',
'reply_to' => 'reply-queue',
'application_headers' => [
'X-Custom-Header' => 'value'
]
]);
// Access properties in consumer (using dynamic call)
$amqp->consume('queue', function ($message, $resolver) {
$priority = $message->getPriority();
$correlationId = $message->getCorrelationId();
$headers = $message->getHeaders();
});New method to retrieve connection configurations programmatically.
$amqp->getConnectionConfig() - Get configuration for a specific connection$amqp = app('Amqp');
$config = $amqp->getConnectionConfig('production');
// Returns: ['host' => 'localhost', 'port' => 5672, ...]qos_prefetch_count, qos_prefetch_size, and qos_a_globalwait_for_confirms and publish_timeoutSingleton Behavior - Fixed issue where Publisher and Consumer properties persisted between calls
Connection Management - Improved connection and channel cleanup
Configuration Handling - Enhanced configuration provider
Queue Declaration - Fixed PRECONDITION_FAILED errors
Test Environment - Improved test reliability
rabbitmq:3-management Docker imageThis release maintains full backward compatibility with previous versions:
None - This release is fully backward compatible.
No migration required. All existing code will continue to work. To use new features:
config/amqp.php if you want to use Management API featuresAll methods should be called dynamically:
// Get Amqp instance from container
$amqp = app('Amqp');
// or
$amqp = resolve('Amqp');
// Publish messages (using dynamic call)
$amqp->publish('routing-key', 'message');Dynamic Instance (required for all methods including consume(), rpc(), listen(), publish(), and management methods):
// Get Amqp instance from container
$amqp = app('Amqp');
// or
$amqp = resolve('Amqp');
// Use instance methods
$amqp->consume('queue', function ($message, $resolver) {
// Handle message
});
$amqp->rpc('rpc-queue', 'request', [], 30);
$amqp->listen(['key1', 'key2'], function ($message, $resolver) {
// Handle message
});
// Management methods
$amqp->queuePurge('my-queue', ['queue' => 'my-queue']);
$amqp->getQueueStats('my-queue', '/');Note: All methods including publish(), consume(), rpc(), listen(), and all management methods must be called on an instance resolved from the container using $amqp = app('Amqp') or $amqp = resolve('Amqp').
Future improvements planned:
Special thanks to all contributors and the community for feedback and testing.
rpc(), reply(), listen())For issues, questions, or contributions, please visit:
docs/ directoryRelease Date: 2025
Version: 3.1.0
Status: Ready
Full Changelog: 2.1.2...v3.1.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →