Cqrs
(CQRS) Command/Query bus implementation for Spiral Framework
Install / Use
/learn @spiral-packages/CqrsREADME
(CQRS) Command/Query bus implementation for Spiral Framework
It's a lightweight messaging facade. It allows you to define the API of your model with the help of messages.
- Command messages describe actions your model can handle.
- Query messages describe available information that can be fetched from your (read) model.
Requirements
Make sure that your server is configured with following PHP version and extensions:
- PHP 8.1+
- Spiral framework 3.0+
Installation
You can install the package via composer:
composer require spiral-packages/cqrs
After package install you need to register bootloader from the package.
protected const LOAD = [
// ...
\Spiral\Cqrs\Bootloader\CqrsBootloader::class,
];
Note: if you are using
spiral-packages/discoverer, you don't need to register bootloader by yourself.
Usage
You can also register command and query handlers via attributes
Commands
Command definition
class StoreUser implements \Spiral\Cqrs\CommandInterface
{
public function __construct(
public Uuid $uuid,
public string $username,
public string $password,
public \DateTimeImmutable $registeredAt,
) {
}
}
Command handler definition
To register command handler you just need to add attribute on method that should be invoked.
class StoreUserHandler
{
public function __construct(
private EntityManagerInterface $entityManager
) {
}
#[\Spiral\Cqrs\Attribute\CommandHandler]
public function __invoke(StoreUser $command)
{
$this->entityManager->persist(
new User(
$command->uuid,
$command->username,
$command->password,
$command->registeredAt
)
);
$this->entityManager->run();
}
}
Dispatch command
use Ramsey\Uuid\Uuid;
class UserController
{
public function store(UserStoreRequest $request, \Spiral\Cqrs\CommandBusInterface $bus)
{
$bus->dispatch(new StoreUser(
$uuid = Uuid::uuid4(),
$request->getUsername(),
$request->getPassword(),
new \DateTimeImmutable()
));
return $uuid;
}
}
Queries
Query definition
class FindAllUsers implements \Spiral\Cqrs\QueryInterface
{
public function __construct(
public array $roles = []
) {
}
}
class FindUserById implements \Spiral\Cqrs\QueryInterface
{
public function __construct(
public Uuid $uuid
) {
}
}
Query handler definition
class UsersQueries
{
public function __construct(
private UserRepository $users
) {
}
#[\Spiral\Cqrs\Attribute\QueryHandler]
public function findAll(FindAllUsers $query): UserCollection
{
$scope = [];
if ($query->roles !== []) {
$scope['roles'] = $query->roles
}
return new UserCollection(
$this->users->findAll($scope)
);
}
#[\Spiral\Cqrs\Attribute\QueryHandler]
public function findById(FindUserById $query): UserResource
{
return new UserResource(
$this->users->findByPK($query->uuid)
);
}
}
Dispatch queries
use Ramsey\Uuid\Uuid;
class UserController
{
public function index(UserFilters $filters, \Spiral\Cqrs\QueryBusInterface $bus)
{
return $bus->ask(
new FindAllUsers($filters->roles())
)->toArray();
}
public function show(string $uuid, \Spiral\Cqrs\QueryBusInterface $bus)
{
return $bus->ask(
new FindUserById(Uuid::fromString($uuid))
)->toArray();
}
}
Testing
composer test
License
The MIT License (MIT). Please see License File for more information.
Related Skills
node-connect
349.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.2kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
