somework/cqrs-bundle
A CQRS bundle for Laravel that separates commands from queries with handler registration, buses, and middleware. Structure write and read flows cleanly while keeping integration lightweight and framework-friendly.
transports.command_async / transports.event_async authoritative even when no async bus exists. That turns a previously implicit design choice (relay handles rows in-process vs. a dedicated worker consumes them) into an explicit, configurable one — a decision PMs and platform leads should settle deliberately, because it changes deployment topology and operational runbooks.messenger:consume <transport> for the configured transports, or point them at sync:// to preserve prior behaviour. That's a staffing and deployment-pipeline consequence, not just a code change.DelayStamp), deduplication for at-least-once delivery, and handler-less events as a first-class pattern.Consider it when:
UPGRADE.md.Look elsewhere when:
LogicException if Messenger's pass hasn't run. Custom passes touching bus middleware must sit below priority −25. This is expert-level territory.sync://, which partly negates the async value proposition.Release-specific adoption notes (v0.5.1): no breaking API or config changes, but it is a required upgrade before Symfony 8.2 — 0.5.0 is materially broken there (missing middleware, NoHandlerForMessageException on handler-less events, EnvelopeAware failures, container not compiling with outbox enabled, routing ignored). Treat the "no breaking changes" claim carefully: the outbox transport fix is a silent behaviour change for outbox-only apps, and rows written by 0.5.0 retain their empty transport and will keep being handled in the relay process. Pin ^0.5.1 explicitly; do not float on ^0.5.0.
For executives: We're evaluating a small open-source component that provides the messaging backbone for our PHP/Symfony services — it makes sure business events are reliably published when data changes, and gives us tracing and de-duplication without building it ourselves. The latest patch (0.5.1) is a compatibility release: it fixes a real breakage on the next Symfony version and closes a configuration gap for teams not running background message workers. There are no API changes, but the upgrade requires a short operational step (running message workers, or a config switch). Main risk is that the project is pre-1.0 and moves quickly; mitigation is version pinning and a documented upgrade runbook.
For engineering: Adopt only on ≥0.5.1, and upgrade in the same change window as Symfony 8.2 — 0.5.0 is broken on 8.2 in five distinct ways. Budget for two operational chores: (1) audit your own compiler passes; anything that must observe or mutate bus middleware lists needs priority below −25, since the bundle's passes now run at −24 and fail loudly with a LogicException if Messenger's MessengerPass hasn't executed; (2) if you use the outbox without an async bus, decide per transport between messenger:consume <transport> (rows now carry the configured transport) and sync:// (preserves the old in-relay behaviour). Expect pre-existing outbox rows from 0.5.0 to keep their empty transport and continue in the relay — plan a drain or accept the mixed behaviour. Upside: handler-less events, EnvelopeAware handlers, #[AsMessageHandler(transport: …)] routing and outbox compilation all work again on 8.2, and DoctrineBridge 8.2's transaction middleware is correctly skipped under the outbox regardless of service id. Net read: solid capability, thin operational margin — worth a time-boxed spike, not a blind production rollout.
How can I help you explore Laravel packages today?