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

Bus Laravel Package

laravelcollective/bus

A command bus for Laravel that dispatches commands to their handlers, with middleware support and container integration for cleaner, decoupled application logic.

View on GitHub
Deep Wiki
Context7

Getting Started

laravelcollective/bus is the Laravel 5.0-era Illuminate\Bus command bus, extracted into the Collective\Bus namespace so it could keep working after the framework replaced it with the pipeline-based dispatch()/Jobs system in 5.1. Practically everything useful lives in the 5.0 bus: a Dispatcher, a CommandBus contract, the SelfHandling/SelfHandlingCommand traits, a ShouldBeQueued marker interface, and the DispatchesCommands trait you mix into controllers. Treat the src/ directory as the documentation — the README is thin and there is no config file, migrations, or published assets.

Minimal setup:

  1. composer require laravelcollective/bus — on a modern Laravel this will almost certainly fail on constraints (last tag is December 2015, pinned to PHP 5.x / Laravel ~5.0–5.1). The realistic path today is dev-master on a legacy app, or vendoring the handful of classes you need.
  2. Register the service provider in config/app.php providers: Collective\Bus\BusServiceProvider::class. This is what binds the dispatcher into the container (typically aliased onto Illuminate\Contracts\Bus\Dispatcher), so provider order matters if anything resolves the bus in its own register().
  3. Add the DispatchesCommands trait to App\Http\Controllers\Controller (or a base service class) to get dispatch() / dispatchFrom().
  4. Verify the binding resolves before writing features: app(Illuminate\Contracts\Bus\Dispatcher::class) should return the collective dispatcher, not the framework one.

First use case to try: a single side-effecting action moved out of a controller. Create App\Commands\RegisterUser as a plain DTO with public properties, create App\Commands\RegisterUserHandler with a handle(RegisterUser $command) method, then $this->dispatch(new RegisterUser($input)) from the controller. If that round-trips, the bus is wired correctly; everything else is variants on it.

Implementation Patterns

Command + handler pairs (the default). Keep commands as dumb, serializable value objects — public scalar/array properties, no dependencies injected beyond what dispatchFrom marshals. Put all behaviour and injected services (UserRepository, Mailer, etc.) in the handler. The dispatcher resolves handlers out of the container by convention (CommandClass → CommandClassHandler); if you rename or namespace things asymmetrically, you'll get a container resolution exception rather than a helpful message, so bind handlers explicitly when the convention doesn't hold.

Self-handling commands. For small actions where the split is ceremony, implement the SelfHandling trait on the command and give it its own handle(). Good for one-off actions dispatched in two or three places; bad for anything you want to unit test in isolation or queue, since you end up injecting services into the command itself.

dispatchFrom for HTTP input. $this->dispatchFrom(RegisterUser::class, $request) marshals request input onto the command's public properties. This is the 5.0 idiom that FormRequest + Jobs later replaced. Two consequences: only public properties are populated, and the marshalling is a straight assignment — so validation belongs in the command's rules (if you're using the validating-command pattern) or explicitly at the top of the handler. Don't rely on the request object leaking into the command.

Queueing. Implement ShouldBeQueued on the command and the dispatcher pushes it through the queue resolver instead of calling the handler inline. You need the queue traits the package/framework provides (InteractsWithQueue, SerializesModels, etc.) on the command, and the command's $connection/$queue properties select the destination. This is where the package earns its keep in a legacy app: you can convert a synchronous handler to a queued one by adding an interface and nothing else.

Pipelines and composition. The dispatcher supports a pipeThrough array of middleware classes wrapping handle — useful for cross-cutting concerns (transaction wrapping, logging, authorization) without touching handlers. Reserve it for genuinely universal behaviour; command-specific concerns belong inside the handler.

Controllers stay thin. A controller method should be: build command, dispatch, redirect/respond. Handler = transaction boundary + domain work. Fire domain events from inside the handler after the work commits, not from the controller before dispatch — otherwise a failed handler leaves you with an event that claims success.

Gotchas and Tips

  • This package is archived and superseded. Laravel 5.1's Illuminate\Bus\Dispatcher with the dispatch() helper and DispatchesJobs is the replacement; 5.5+ added Bus::fake() and job middleware. Only adopt this for an app already rooted in the 5.0 idiom. Never introduce it into a new codebase.
  • Two dispatchers, one container. The most common failure is resolving Illuminate\Contracts\Bus\Dispatcher and getting the framework's dispatcher, so queued commands silently execute synchronously or fail to resolve handlers. Confirm which implementation you actually got, and check that your provider is registered after the framework's bus provider.
  • Handler resolution is convention + container magic. A typo in a handler class name surfaces as an unhelpful reflection/binding exception. Bind handler interfaces explicitly in a service provider for anything non-trivial, and you also gain the ability to swap implementations in tests.
  • Queued command serialization. Commands carrying Eloquent models, closures, or un-serializable services will break on the queue worker, not at dispatch time. Use SerializesModels where available and keep commands to scalars/IDs when you can.
  • dispatchFrom is silent about missing input. A property the request never populates stays at its default (often null) and the handler receives it without complaint. Validate in the handler, or at minimum assert command invariants in a constructor/handle guard.
  • Nested dispatch loops. Dispatching from inside a handler is legal but easy to make recursive, and dispatching a queued command from a queued handler can fan out unexpectedly. Flatten to explicit sequential dispatches or events.
  • Testing strategy. There's no Bus::fake() here. Mock or swap the CommandBus/dispatcher binding to assert what was dispatched, and separately instantiate handlers directly with mocked collaborators — the handler is just a class with a handle() method, so most of your test suite shouldn't need the bus at all.
  • No config to tune. Queue choice, connections, and handler resolution all happen through the command class and container bindings; if you need configurability, add your own provider rather than expecting package config.
  • Extension points worth knowing: the dispatcher's queue resolver (swap to route commands to a specific connection), the pipeThrough middleware array, and container bindings for handlers. Those three cover nearly every customization request.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core