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

Command Bus Laravel Package

micro-module/command-bus

A lightweight command bus for Laravel micro-modules that dispatches commands to their handlers, supports middleware pipelines, and keeps controllers thin by separating request handling from business logic.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a micro-module "common" library for a command bus — expect it to ship an interface (something like Command, CommandHandler, and a CommandBus dispatcher) plus a Laravel service provider that binds the bus into the container. Because it is a common library rather than a full framework, it is likely meant to be wired into other micro-modules rather than used standalone.

Minimal steps:

  1. composer require micro-module/command-bus — note the last release was May 2021, so check that the version constraint still resolves against your PHP/Laravel version. If it does not, you will need to fork it or add an inline repository with a dev-main constraint.
  2. If Laravel auto-discovery is supported, the service provider should register automatically; otherwise add it to config/app.php under providers.
  3. Inspect vendor/micro-module/command-bus/src first — the README is thin, and the actual contract (method names like dispatch vs handle, whether handlers return values, whether the bus is synchronous) lives in the source. Read the CommandBus and handler-marker interfaces before writing anything.
  4. Write your first pair: a plain Command DTO holding the input, and a Handler class with the package's expected method signature. Register the mapping (attribute, config array, or container binding — depends on which discovery mechanism the package exposes).
  5. Dispatch from a controller or another module's service and assert the handler was invoked.

First use case: extracting a single controller action's write-side logic into a command so that the same operation can be called from an HTTP controller, a queued job, and a console command without duplication.

Implementation Patterns

One command, one public method. Treat commands as immutable DTOs with constructor-promoted properties and no setters. Handlers should be plain classes resolved from the container so you can type-hint repositories and other services.

Controller → bus handoff. Keep controllers thin: build the command from the validated request, dispatch it, and map the result (if the bus returns one) to a resource. Do not let the controller reach into the handler.

Module boundaries. Because this is a micro-module package, the intended workflow is that each module declares its own commands and registers its own handlers, while the transport (the bus) is shared. Put the registration in each module's service provider and keep the bus binding in app only.

Testing. In unit tests, either instantiate the handler directly (fastest, no bus dependency) or swap the bus for a spy/fake if the package provides one. In feature tests, assert the observable side effect (database row, event dispatched) rather than mocking the bus — the bus is an implementation detail.

Queued commands. If the bus supports queueing, make commands Serializable (plain scalar/array properties only, no closures or Eloquent models). Keep the queued command small and re-fetch state inside the handler.

Middleware pipeline. If the package exposes a middleware/pipe interface, use it for cross-cutting concerns (transactions, logging, auth checks) instead of repeating them in handlers. Define the order explicitly — the order is almost never documented.

Cross-module dispatch. Where a module needs to trigger a command owned by another module, depend on the command class (an interface or DTO) rather than the handler. This keeps the dependency graph acyclic.

Gotchas and Tips

  • Maintenance risk is the headline problem. Zero stars, zero dependents, last release over four years ago. There is no community to catch a breaking change in a future Laravel release. Before adopting, vendor the source into your own namespace or fork it — treating it as an external dependency you cannot patch is a real operational hazard.
  • Undocumented handler contract. The biggest day-one friction is guessing whether handlers are discovered by attributes, by a handles() method returning a class string, or by a config map. Grep the package's src for class_exists, ReflectionClass, and handle to find the mechanism before you write handlers.
  • Return values vs side effects. Many small command buses discard the handler's return value and treat commands as fire-and-forget. If you need a result (an ID, a status), confirm the bus actually propagates it; otherwise return the ID via an event or a property set after dispatch.
  • Transaction boundaries. If the bus dispatches queued commands or events from inside a handler, a DB::transaction wrapped around the dispatch will not cover the queued work. Decide explicitly whether the transaction belongs inside the handler or around the synchronous portion only.
  • Container resolution. Handlers are usually resolved through the container, so constructor injection works — but only if the handler is bound or auto-resolvable. A handler with a primitive constructor argument will throw an unresolvable-dependency exception that is easy to misread as a "handler not found" error.
  • Debugging silent failures. With no logging middleware, a mis-registered handler often just throws a generic "no handler for command" exception. Add a thin logging decorator around the bus early — it will save hours.
  • Version pinning. Pin to the exact release you tested ("micro-module/command-bus": "1.x" with a lock file committed) and add a smoke test that dispatches one command, so a transitive update in your own stack surfaces as a red test rather than a production surprise.
  • Extension points. If you need to evolve the library, prefer wrapping it: add your own App\Bus\CommandBus that delegates to the package bus, so replacing the package later is a one-file change rather than a refactor across every module.
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource