bschmitt/laravel-amqp
Laravel AMQP is a wrapper for RabbitMQ that makes it easy to publish and consume messages from Laravel apps. Configure connections, exchanges, and queues; publish payloads; and run consumers or listeners with a clean facade and Artisan commands.
Build vs. buy for the messaging substrate. This release moves the package from "an AMQP client you wrap yourself" to "a Laravel-first microservice toolkit." That changes the calculus on several in-house platform components. If your roadmap contains any of the following, evaluate this package before writing it yourself:
Rpc layer (typed request/response DTOs, Rpc::call(), Rpc::serve(), typed RpcException vs. RpcTimeoutException) replaces a bespoke request/reply convention most teams hand-roll on top of RabbitMQ. Note this is a style of RPC, not gRPC: JSON/typed DTOs over RabbitMQ, no protobuf, no HTTP/2, no streaming, no cross-language clients.Saga::make()->step(...)->compensate(...) gives a readable orchestration API. Treat it as an in-process orchestration helper, not a durable workflow engine — saga state lives in your worker, so a crashed worker mid-compensation leaves you reconciling manually. Good for 2–4 step flows with idempotent compensations; insufficient for long-running, human-in-the-loop, or days-long workflows.Amqp::deadLetters()->for($q)->count()/messages()/replayTo()/purge() and php artisan amqp:monitor --json are the features that most often justify adoption on their own — they convert "we need someone to build a DLQ replay script" into a sprint-sized non-item. The dashboard is a JSON snapshot, not a metrics backend; plan to scrape it into whatever you already run.MessageStore give you the primitives for "why did this order get charged twice?" investigations. The shipped InMemoryMessageStore is a test/small-workload default; a production decision here means committing to implementing MessageStoreInterface against Eloquent/Redis/S3 — budget that work explicitly rather than treating it as included.#[Retry] + RetryStrategy (fixed/linear/exponential with jitter) lets retry semantics live next to the handler instead of in config prose. PHP 8+ only for the attribute; PHP 7.x silently ignores it, which is convenient but means a PHP 7.3 deployment gets different runtime behavior than staging on PHP 8 — a real operational footgun worth a policy decision.ShouldPublishToAmqpInterface turns event(new OrderCreated(...)) into a publish, opt-in via config. This lowers the cost of "just emit an event" for product teams, which is usually the difference between an event-driven design that survives contact with deadlines and one that doesn't.Roadmap sequencing this enables. The release is a coherent capability stack, and it should be sequenced rather than adopted wholesale: (1) upgrade for free and use DLQ management + monitoring, since these are standalone and low-risk; (2) adopt typed message dispatch and async events where teams are already publishing; (3) adopt the RPC layer for new service boundaries only; (4) treat sagas, MessageStore durability, and causation-ID propagation as a platform initiative with an owner, not a library upgrade.
What it does not decide for you. No outbox/transactional-publish guarantee is described — publishing to RabbitMQ is still not atomic with your database write, so "did the order commit but the event not publish?" remains your problem. No exactly-once delivery. No schema registry or versioning story for DTO evolution beyond reflection hydration. No managed hosting. These are the gaps where a build-or-adopt decision still stands on its own.
Explicitly do not adopt this to replace: a cross-language RPC contract (gRPC/protobuf, or plain REST), durable workflow orchestration (Temporal, Laravel Workflow), or a full observability stack (OpenTelemetry exporters, Prometheus). It overlaps with all three at the edges and is worse than each at its core.
Strong fit:
TypedMessage::make()/dispatch()/dispatchLater()) without adopting a heavier framework or schema toolchain.Look elsewhere, or wait:
Adoption gate before production: confirm integration tests exercise the RPC layer, saga compensation paths, and DLQ replay against a real broker — the notes claim unit coverage, which is not the same thing. Verify the x-rpc-service/x-rpc-request/x-causation-id headers survive your existing middleware and any broker-level policy rewriting. And decide up front whether broadcast_laravel_events is on, because turning it on later changes publish volume across every team that ever fired a domain event.
For executives — one paragraph. Our messaging package shipped a substantial upgrade that converts a low-level RabbitMQ client into a Laravel-native toolkit for service communication, multi-step transactions, retries, dead-letter handling, and tracing. The upgrade itself is zero-migration and backward compatible, so there is no forced work; the value is that several capabilities on our platform backlog — DLQ replay tooling, queue health monitoring, a typed internal RPC convention, correlation/causation tracing — now come off the backlog roughly for the cost of integration and review. We can adopt it incrementally, feature by feature, with no vendor commitment and no re-platforming, and we retain full exit options because it sits on RabbitMQ rather than replacing it.
For engineering leadership — the trade. We get leverage and speed at the cost of a larger third-party surface area and a maintainer-dependency we should explicitly accept or reject. Concretely: it is additive and opt-in, PHP 7.3–8.5 and Laravel 8–13 are supported, and 3.4.0 code keeps working unchanged. The risks are (a) significant new capability shipped in a patch version, which suggests the maintainer's versioning discipline doesn't match our dependency policy; (b) the durable defaults are not durable — InMemoryMessageStore and in-process saga state are fine for tests and demos, not for money paths; (c) no exactly-once or transactional-publish guarantee, so we still own the outbox and idempotency work; and (d) unit coverage is claimed, integration coverage against a real broker is not. My recommendation is to adopt the operational wins now (dead-letter management, amqp:monitor, typed dispatch) because they are isolated and reversible, and to gate the RPC layer and sagas behind a small pilot that proves them on one non-critical service before we standardize.
For the teams doing the work — the ask. Two sprints, phased: Sprint 1, upgrade and pin, wire amqp:monitor --json into existing alerting, and start using Amqp::deadLetters() for the top three queues that page us. Sprint 2, pilot Rpc::service() and Saga on one bounded flow, with a written position on where saga state lives and what happens on worker crash. In parallel, someone owns the decision on a production MessageStoreInterface implementation, because that's the difference between "we have an audit trail" and "we have a class named MessageStore." Document the PHP 7.3-vs-8.x #[Retry] behavior split so nobody assumes retries are firing in an environment where the attribute is silently a comment.
How can I help you explore Laravel packages today?