Download the PHP package different-universe/laravel-cqbus-mediator without Composer

On this page you can find all versions of the php package different-universe/laravel-cqbus-mediator. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-cqbus-mediator

Laravel CQBus Mediator

Lightweight CQS/CQRS-style mediator for Laravel applications. The package lets you describe application use cases as small command, query, and internal handler classes, route messages to handlers automatically via PHP attributes, and wrap execution with Laravel pipelines.

Instead of calling large service classes from controllers, you dispatch an explicit message:

Motivation

Controllers are usually a poor place for business logic. They should deal with the HTTP layer: request data, validation, authentication context, response shape, status codes, redirects, headers, and framework-specific concerns.

Business operations are easier to understand and test when they are modeled as separate application units. A CreateOrderHandler, RefundPaymentHandler, or LookupCustomerBalanceHandler represents one concrete use case that can be reused from controllers, console commands, queue jobs, event listeners, tests, or any other entry point.

The common "fat controller" problem appears when HTTP details, application flow, persistence, domain rules, authorization checks, logging, and side effects grow together in the same method. The result is hard to test, hard to reuse outside HTTP, and hard to change without pulling on hidden dependencies.

Classic service classes help, but they often drift into broad buckets such as OrderService, UserService, or PaymentService. Over time they collect many unrelated methods, their names stop describing a single operation, and cross-cutting behavior such as transactions, tracing, tenant context, or query caching becomes inconsistent.

This package pushes the code toward smaller use-case handlers:

Features

Requirements

Installation

Install the package:

Publish the config file:

Optionally publish stubs for generator customization:

The service provider is registered automatically through Laravel package discovery.

If package discovery is disabled, register the provider manually:

Configuration

After publishing, the config is available at config/mediator.php:

Basic Usage

Create a message:

Create a handler:

Dispatch through the contract:

Or dispatch through the facade:

The value returned by handle() is returned from the mediator. If an internal handler chain is configured through an output channel, the final internal handler result is returned.

Commands And Queries

#[CommandHandler] and #[QueryHandler] work the same way at the API level. Both mark a class as a discoverable handler, both support automatic or explicit input channels, both can define an output channel, and both can be wrapped with pipelines.

The difference is mostly business-level:

The technical benefit of separating them is that commands and queries can have different configured pipelines. For example, commands can run through transactions and retries, while queries can run through cache lookup.

Command example:

Query example:

Handlers are resolved through the Laravel container, so constructor injection works normally.

Handler requirements:

Input Channels

There are two channel styles.

Automatic typed channel:

When no channel is passed to the attribute, the channel is derived from the type of the single handle() parameter. In this example, the input channel is CreateOrder::class.

Union types are supported and register the same handler for each message class:

Restrictions for automatic typed channels:

The channel is the exact class name from the type declaration. Inheritance is not considered: a handler registered for BaseCommand::class will not be found by send(new CreateOrder(...)) unless the actual message class is also registered as an input channel.

Explicit named channel:

When an explicit channel is provided, it takes precedence over the handle() parameter type. This is useful for string channels, generic payloads, integration-style messages, or cases where a dedicated message class would be unnecessary.

For named channels, the parameter type does not affect routing. A handler may have no handle() parameter at all, or one parameter with any type you need for that channel. If a parameter is present, it must still be the only parameter.

Dispatching

Dispatch by message class:

send() accepts only an object and routes it by $message::class.

Dispatch by explicit channel:

sendToChannel() accepts any payload.

Both methods are available on the contract and the facade:

Internal Handlers

Internal handlers run after the main command/query handler. They receive the result of the previous handler and may transform it before passing it to the next internal handler.

They are useful for explicit post-processing chains: audit trail storage, normalization, enrichment, or a final response transformation.

Main handler with output channel:

Internal handler chain:

Important rules:

The chain stops when a handler has no outputChannel. In that case, the value returned by that handler becomes the final mediator result.

If an output channel points back to an already visited internal channel, the mediator throws RuntimeException with a circular output channel message.

Pipelines

The package uses Laravel Illuminate\Pipeline\Pipeline. Conceptually, pipelines work like middleware: a pipe receives the payload, calls $next($payload), and can run logic before or after the next pipe/handler.

Pipelines can be configured globally:

Or locally on a command/query handler:

Multiple local pipelines can be declared with repeatable attributes:

Or with several pipes in one attribute:

Pipeline order:

  1. global_pipelines
  2. command_pipelines or query_pipelines
  3. local pipelines from #[Pipeline(...)]

Because Laravel pipelines wrap the next stage, "before" logic runs from first to last, while "after" logic unwinds from last to first.

Parameterized Pipelines

Laravel pipeline strings with parameters are supported.

Via attribute:

Via config:

Excluding Configured Pipelines

Use #[WithoutGlobalPipeline] to remove selected configured pipeline entries for a handler:

Several configured pipelines can be excluded with a repeatable attribute:

Or with several pipes in one attribute:

The exclusion is applied to the configured pipeline list resolved for the handler type: global_pipelines plus command_pipelines for commands, or global_pipelines plus query_pipelines for queries.

WithoutGlobalPipeline compares the complete pipeline entry. If config contains a parameterized entry, you must exclude the same string:

This will not remove it:

Use the full entry instead:

Use #[WithoutAllGlobalPipelines] to remove all configured pipelines for this handler and keep only local #[Pipeline] entries:

Pipeline classes should be valid handler-like classes: instantiable classes with public non-static handle() methods.

Pipelines are supported for command and query handlers only. Internal handlers are not individually wrapped with pipelines.

Cache And Production Mode

In development, runtime discovery is convenient: the mediator scans configured paths and builds handler maps automatically.

In production, cache mode is always preferred. It compiles discovered handlers, internal handlers, output channels, and pipeline lists into one PHP cache file, so the application can load the prepared map instead of running discovery and reflection during runtime.

Create the cache:

Clear the cache:

These commands are also wired into Laravel optimization:

optimize runs mediator cache generation, and optimize:clear removes the mediator cache.

Recommended production deploy flow:

If handlers, attributes, output channels, pipeline attributes, configured pipelines, or discovery paths change, rebuild the mediator cache.

Console Commands

Generator commands:

By default, generated handlers are placed under App\Mediator and receive the Handler suffix. Both behaviors can be changed in config/mediator.php.

Cache commands:

Published stubs can be customized in the application's stubs directory:

Laravel Octane

The package works with Laravel Octane. The mediator is registered as a singleton and can be warmed when an Octane worker starts.

To warm the mediator service, add it to warm in config/octane.php:

This makes the worker resolve the mediator up front instead of doing it on the request.

Facade And Contract

For application code, prefer injecting the contract:

The facade is convenient for examples, tests, seeders, small scripts, or places where facade style is already used:

Both expose:

Error Handling

Common exceptions:

DifferentUniverse\CqbusMediator\Exceptions\HandlerNotFoundException

Thrown when no command/query handler exists for an input channel or message class, or when an output channel references a missing internal handler.

Typical causes:

DifferentUniverse\CqbusMediator\Exceptions\InvalidHandlerException

Thrown during discovery/cache generation when a handler or pipeline class is structurally invalid.

Typical causes:

RuntimeException

Thrown by the mediator when an internal output channel chain becomes circular.

Testing

Feature-test a full mediator flow:

Unit-test a handler directly when you want a narrow test:

Replace handler dependencies through the Laravel container:

Test a flow with pipelines by configuring discovery paths and pipeline config in the test:

For internal handler chains, assert the final result or observable side effects:

When tests modify mediator config or cache files, reset that state between tests. In particular, call MediatorConfig::flushCachedPipelines() after changing configured pipelines, clear facade/container instances when needed, and remove bootstrap/cache/mediator.php if a test creates it.

Best Practices

License

Laravel CQBus Mediator is open-sourced software licensed under the MIT license.


All versions of laravel-cqbus-mediator with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
illuminate/container Version ^11.0 || ^12.0 || ^13.0
illuminate/console Version ^11.0 || ^12.0 || ^13.0
illuminate/contracts Version ^11.0 || ^12.0 || ^13.0
illuminate/pipeline Version ^11.0 || ^12.0 || ^13.0
illuminate/support Version ^11.0 || ^12.0 || ^13.0
spatie/php-structure-discoverer Version ^2.3
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package different-universe/laravel-cqbus-mediator contains the following files

Loading the files please wait ...