PHPackages                             spiral-packages/cqrs - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. spiral-packages/cqrs

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

spiral-packages/cqrs
====================

Lightweight message bus supporting CQRS for Spiral Framework

v2.3.0(2y ago)816.9k↑23.3%2[2 issues](https://github.com/spiral-packages/cqrs/issues)[1 PRs](https://github.com/spiral-packages/cqrs/pulls)MITPHPPHP ^8.1

Since May 30Pushed 2y ago2 watchersCompare

[ Source](https://github.com/spiral-packages/cqrs)[ Packagist](https://packagist.org/packages/spiral-packages/cqrs)[ Docs](https://github.com/spiral-packages/cqrs)[ RSS](/packages/spiral-packages-cqrs/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (5)Dependencies (10)Versions (8)Used By (0)

(CQRS) Command/Query bus implementation for Spiral Framework
============================================================

[](#cqrs-commandquery-bus-implementation-for-spiral-framework)

[![PHP](https://camo.githubusercontent.com/6f9980510fe853bdad4bef37541aeaf331c767a57faa1a710da1518c4df2b5e8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f73706972616c2d7061636b616765732f637172732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spiral-packages/cqrs)[![Latest Version on Packagist](https://camo.githubusercontent.com/ee1ed4172faf81c17e469d0f38cea5c8a0bed07e5103b35207d0db49389506c2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f73706972616c2d7061636b616765732f637172732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spiral-packages/cqrs)[![Total Downloads](https://camo.githubusercontent.com/45d9d3167d691301b4fabede620f0eac8706f1c3cbb6e7686a6a49f84d324d91/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f73706972616c2d7061636b616765732f637172732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spiral-packages/cqrs)[![run-tests](https://github.com/spiral-packages/cqrs/actions/workflows/run-tests.yml/badge.svg)](https://github.com/spiral-packages/cqrs/actions/workflows/run-tests.yml)

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
------------

[](#requirements)

Make sure that your server is configured with following PHP version and extensions:

- PHP 8.1+
- Spiral framework 3.0+

Installation
------------

[](#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`](https://github.com/spiral-packages/discoverer), you don't need to register bootloader by yourself.

Usage
-----

[](#usage)

You can also register command and query handlers via attributes

### Commands

[](#commands)

#### Command definition

[](#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

[](#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

[](#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

[](#queries)

#### Query definition

[](#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

[](#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

[](#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
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance15

Infrequent updates — may be unmaintained

Popularity34

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 65.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~109 days

Recently: every ~137 days

Total

6

Last Release

900d ago

Major Versions

v1.0.0 → v2.0.02022-05-30

PHP version history (2 changes)1.0.x-devPHP ^8.0

v2.0.0PHP ^8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/773481?v=4)[Pavel Buchnev](/maintainers/butschster)[@butschster](https://github.com/butschster)

---

Top Contributors

[![butschster](https://avatars.githubusercontent.com/u/773481?v=4)](https://github.com/butschster "butschster (19 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (8 commits)")[![HanakJakub](https://avatars.githubusercontent.com/u/17723998?v=4)](https://github.com/HanakJakub "HanakJakub (1 commits)")[![msmakouz](https://avatars.githubusercontent.com/u/67324318?v=4)](https://github.com/msmakouz "msmakouz (1 commits)")

---

Tags

command-buscqrsphpphp8query-busspiralspiral-frameworkcommand buscqrsspiralspiral-packagesquery-bus

###  Code Quality

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/spiral-packages-cqrs/health.svg)

```
[![Health](https://phpackages.com/badges/spiral-packages-cqrs/health.svg)](https://phpackages.com/packages/spiral-packages-cqrs)
```

###  Alternatives

[spiral/temporal-bridge

Temporal integration package for Spiral Framework

58901.5k](/packages/spiral-temporal-bridge)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
