lsr / cqrs
Laser framework CQRS implementation.
Requires
- php: >=8.4
- lsr/core: ^0.3 || ^0.4 || ^0.5
- lsr/interfaces: ^0.3
- lsr/logging: ^0.3
- lsr/serializer: ^0.3
- nette/di: ^3.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.95
- phpstan/extension-installer: ^1.2
- phpstan/phpstan: ^2.0
- phpstan/phpstan-nette: ^2.0
- phpunit/phpunit: ^12
- roave/security-advisories: dev-latest
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-08 14:50:07 UTC
README
lsr/cqrs provides a synchronous command bus backed by the LSR application's service container, an interface for application-provided asynchronous dispatch, and a small query contract.
Requirements
- PHP
>=8.4. - LSR Core
^0.3 || ^0.4 || ^0.5; LSR Interfaces, Logging and Serializer^0.3; Nette DI^3.2. - A bootstrapped
Lsr\Core\Appand registered command-handler services. - No PHP extensions are explicitly required by this package's manifest; its framework dependencies have their own platform requirements.
Installation
composer require lsr/cqrs
Command dispatch
Register the extension in the application's Nette DI configuration:
extensions: cqrs: Lsr\CQRS\DI\CqrsExtension
The extension expects the Core application service to be named app and registers an autowired Lsr\CQRS\CommandBus.
Implement the following contracts in application code:
- A command implements
CommandInterface. ItsgetHandler(): stringreturns either the handler's concrete class name or its DI service name. - The handler implements
CommandHandlerInterface, withhandle(CommandInterface $command): mixed. Register the handler as an application service. - Inject
CommandBusand calldispatch($command). The bus resolves the handler and returns its result; application exceptions propagate to the caller.
Handler lookup is not convention-based: the command explicitly selects the handler. Class-name lookup uses App::findServicesByType() and selects the first matching service, so avoid registering ambiguous handlers of the same type. Service-name lookup uses App::getService(). Missing or invalid handlers fail rather than silently dropping the command.
See CommandBus for the complete dispatch and handler-resolution contract and CqrsExtension for DI wiring. CommandInterface<T> and the bus's PHPDoc generics describe the returned value to static analysis; they do not enforce a runtime result type.
Asynchronous dispatch
This package does not include a queue transport. Provide and register a service implementing Lsr\CQRS\AsyncCommandBusInterface, then reference its service name:
cqrs: asyncBus: asyncCommandBus
Here asyncCommandBus must already be a service in the application's container. CommandBus::dispatchAsync($command) delegates to that service's dispatch() and returns no result. Calling it without an async bus throws RuntimeException. Serialization, delivery, retry and worker behavior belong to the chosen implementation, not this package.
Queries and instrumentation
QueryInterface defines only get(): mixed. There is no separate query bus in this package.
Synchronous commands can be observed through CommandBus::setLifecycleHook() and the interfaces in src/Lifecycle. Hook failures are isolated from command execution; handler exceptions are still rethrown.
Development
CI runs the checks below on PHP 8.4 and 8.5. From a package checkout:
composer install --prefer-dist --no-interaction --no-progress composer cs vendor/bin/phpstan analyse --no-progress vendor/bin/phpunit --no-coverage
composer cs checks coding style without changing files. Run composer cs:fix (or composer cbf) to apply PHP CS Fixer rules from .php-cs-fixer.php.
The suite needs no external services. CI installs the framework's Redis, PDO SQLite, gettext, fileinfo, SimpleXML and ZIP extensions alongside the DOM, mbstring, XML and XMLWriter extensions used by the development tools. The Redis extension satisfies the dependency platform requirement; these tests do not connect to a Redis server.
AI coding assistance
See LSR Skills for AI agent skills for working with the LSR framework.
License
Licensed under the MIT License.