PHPackages                             lmc/cqrs-bundle - 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. lmc/cqrs-bundle

ActiveSymfony-bundle

lmc/cqrs-bundle
===============

A symfony bundle for CQRS library and its extensions for Queries and Commands

2.1.0(2y ago)115.5k↓37.5%1MITPHPPHP ^8.2

Since May 13Pushed 2y ago10 watchersCompare

[ Source](https://github.com/lmc-eu/cqrs-bundle)[ Packagist](https://packagist.org/packages/lmc/cqrs-bundle)[ RSS](/packages/lmc-cqrs-bundle/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (4)Dependencies (20)Versions (8)Used By (0)

LMC CQRS Bundle
===============

[](#lmc-cqrs-bundle)

[![cqrs-types](https://camo.githubusercontent.com/d2e4a1ae4631bc4819c80a7abc5aa314a298c371e9ab906ccf0eecdd16e00aaa/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f637172732d74797065732d707572706c652e737667)](https://github.com/lmc-eu/cqrs-types)[![Latest Stable Version](https://camo.githubusercontent.com/b3b3debe719781f3984cb1a37f6029bb1674fe2f2147e38dee4bfaa3f59ed56e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c6d632f637172732d62756e646c652e737667)](https://packagist.org/packages/lmc/cqrs-bundle)[![Tests and linting](https://github.com/lmc-eu/cqrs-bundle/actions/workflows/tests.yaml/badge.svg)](https://github.com/lmc-eu/cqrs-bundle/actions/workflows/tests.yaml)[![Coverage Status](https://camo.githubusercontent.com/997e61c1df745fb58002ed39e700be32bbdbb17a9c384f8b228ac372cad7575f/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6c6d632d65752f637172732d62756e646c652f62616467652e7376673f6272616e63683d6d61696e)](https://coveralls.io/github/lmc-eu/cqrs-bundle?branch=main)

> Symfony bundle for CQRS libraries and extensions. It registers services, data collectors etc. by a configuration.

Table of contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Configuration](#configuration)
    - [Routes](#routes)
    - [Tags](#tags)
- [Services](#services)
    - [Handlers](#handlers)
- [Extensions](#extensions)
    - [HTTP](#http)
    - [Solr](#solr)
- [List of all predefined services](#list-of-all-predefined-services-and-their-priorities)

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

[](#installation)

```
composer require lmc/cqrs-bundle
```

Configuration
-------------

[](#configuration)

```
lmc_cqrs:
    profiler: false         # Whether to enable profiler and allow profiling queries and commands [default false]
    debug: false            # Whether to enable debug the CQRS by a console command [default false]

    cache:
        enabled: false                          # Whether to use cache for Queries [default false (true, if you define cache_provider)]
        cache_provider: '@my.cache.provider'    # Service implementing a CacheItemPoolInterface. Required when cache is enabled [default null]

    extension:
        http: false         # Whether should http extension be active (requires a lmc/cqrs-http dependency) [default false]
        solr: false         # Whether should solr extension be active (requires a lmc/cqrs-solr dependency) [default false]
```

### Profiler extended configuration

[](#profiler-extended-configuration)

```
lmc_cqrs:
    profiler:
        enabled: false      # Whether to enable profiler and allow profiling queries and commands [default false]
        verbosity: ''       # Verbosity level (verbose or debug) for a profiler bag - empty string is a default for normal
```

**TIPs**:

- it is advised to set `profiler: '%kernel.debug%'` so it profiles (and registers all services for profiling) only when it is really used
- you can define `profiler` and `debug` in your `dev/lmc_cqrs.yaml` to only allow it in `dev` Symfony environment

**Note**: if you don't enable any of the extension, there will only be a `CallbackQueryHandler` and `CallbackSendCommandHandler`, so you probably need to register your own.

### Routes

[](#routes)

You must register the routes for a CQRS bundle if you enable a profiler.

```
# config/routes.yaml

lmc_cqrs_bundle_routes:
    resource: "@LmcCqrsBundle/Resources/config/routes.yaml"
```

### Tags:

[](#tags)

> Tags are automatically registered, if your class implements an Interface and is registered in Symfony container as a service

- `lmc_cqrs.query_handler` (`QueryHandlerInterface`)
- `lmc_cqrs.send_command_handler` (`SendCommandHandlerInterface`)
- `lmc_cqrs.profiler_formatter` (`ProfilerFormatterInterface`)
- `lmc_cqrs.response_decoder` (`ResponseDecoderInterface`)

With priority

```
services:
    My\CustomQueryHandler:
        tags:
            - { name: 'lmc_cqrs.query_handler', priority: 80 }
```

**Note**: Default priority is `50` and none of the predefined handlers, profilers, etc. has priority higher than `90` (see [complete list below](#list-of-all-predefined-services-and-their-priorities))

Services
--------

[](#services)

Bundle registers all necessary services according to configuration (for example, if you set `http: true` it will automatically register all http handlers, etc.)

Most of the services are registered both by an alias and a class name, so it will be available for autowiring. All interfaces are automatically configured to have a tag (see [Tags](#tags) section above).

### Handlers

[](#handlers)

There are 2 main services, which are essential to the library. Both of them have its interface to represent it, and it is advised to use it via the interface.

#### 1. Query Fetcher Interface

[](#1-query-fetcher-interface)

- implementation `Lmc\Cqrs\Handler\QueryFetcher`
- alias: `@lmc_cqrs.query_fetcher`
- it will find a handler for your query, handles it, decodes a response and caches the result (if cache is enabled)
- provides features:
    - caching
        - requires:
            - cache\_provider (set in the configuration) - service implements `Psr\Cache\CacheItemPoolInterface`
            - Query to implement `Lmc\Cqrs\Types\Feature\CacheableInterface`
        - it allows to cache a decoded result and load it again from cache
    - profiling
        - requires:
            - enabled profiler (in the configuration)
            - Query to implement `Lmc\Cqrs\Types\Feature\ProfileableInterface`
        - it profiles a query, its execution time, response, applied handler and decoders and shows the info in the Symfony profiler

Fetching a query

You can do whatever you want with a response, we will persist a result into db, for an example or log an error.

```
// with continuation
$this->queryFetcher->fetch(
    $query,
    fn ($response) => $this->repository->save($response),
    fn (\Throwable $error) => $this->logger->critical($error->getMassage())
);

// with return
try {
    $response = $this->queryFetcher->fetchAndReturn($query);
    $this->repository->save($response);
} catch (\Throwable $error) {
    $this->logger->critical($error->getMessage());
}
```

#### 2. Command Sender Interface

[](#2-command-sender-interface)

- implementation `Lmc\Cqrs\Handler\CommandSender`
- alias: `@lmc_cqrs.command_sender`
- it will find a handler for your command, handles it, decodes a response
- provides features:
    - profiling
        - requires:
            - enabled profiler (in the configuration)
            - Command to implement `Lmc\Cqrs\Types\Feature\ProfileableInterface`
        - it profiles a command, its execution time, response, applied handler and decoders and shows the info in the Symfony profiler

Sending a command

You can do whatever you want with a response, we will persist a result into db, for an example or log an error.

```
// with continuation
$this->commandSender->send(
    $command,
    fn ($response) => $this->repository->save($response),
    fn (\Throwable $error) => $this->logger->critical($error->getMassage())
);

// with return
try {
    $response = $this->commandSender->sendAndReturn($query);
    $this->repository->save($response);
} catch (\Throwable $error) {
    $this->logger->critical($error->getMessage());
}
```

**Note**: There is no logging feature in the CQRS library, if you need one, you have to implement it by yourself.

### Profiler Bag

[](#profiler-bag)

There is a `profiler bag` service, which is a collection of all profiler information in the current request. The information inside are used by a `CqrsDataCollector`, which shows them in the Symfony profiler.

It requires `profiler: true` in the configuration.

You can access the profiler bag either by:

- `@lmc_cqrs.profiler_bag` (alias)
- `Lmc\Cqrs\Handler\ProfilerBag` (autowiring)
- or access a `CqrsDataCollector` programmatically (see [here](https://symfony.com/doc/current/profiler.html#accessing-profiling-data-programmatically))

Extensions
----------

[](#extensions)

We offer a basic extensions for a common Commands &amp; Queries

- [Http](#http) (using [PSR-7](https://www.php-fig.org/psr/psr-7/))
- [SOLR](#solr) (using [Solarium](https://github.com/solariumphp/solarium))

### Http

[](#http)

> [Http extension repository](https://github.com/lmc-eu/cqrs-http)

Installation

```
composer require lmc/cqrs-http
```

**NOTE**: You will also need an implementation for [PSR-7](https://packagist.org/providers/psr/http-message-implementation), [PSR-17](https://packagist.org/providers/psr/http-factory-implementation) and [PSR-18](https://packagist.org/providers/psr/http-client-implementation) for HTTP extensions to work.

Configuration

```
lmc_cqrs:
    extension:
        http: true
```

Enabling a Http extension will allow a `QueryFetcher` and `CommandSender` to handle a PSR-7 Requests/Response and decode it.

### Solr

[](#solr)

> [SOLR extension repository](https://github.com/lmc-eu/cqrs-solr)

Installation

```
composer require lmc/cqrs-solr
```

Configuration

```
lmc_cqrs:
    extension:
        solr: true
```

Enabling a Solr extension will allow a `QueryFetcher` and `CommandSender` to handle a Solarium Requests/Result and decode it.

#### Solarium Query Builder

[](#solarium-query-builder)

It allows you to build a Solarium request only by defining an Entity with all features you want to provide. See [Solr extension readme](https://github.com/lmc-eu/cqrs-solr#query-builder) for more information.

**Note**: You can specify a tag for your custom applicator by `lmc_cqrs.solr.query_builder_applicator`

List of all predefined services and their priorities
----------------------------------------------------

[](#list-of-all-predefined-services-and-their-priorities)

**Note**: To see a list of all services really registered in your application use `bin/console debug:cqrs` (it requires `debug: true` in your configuration)

### Top most handlers for Commands &amp; Queries

[](#top-most-handlers-for-commands--queries)

InterfaceClassAliasLmc\\Cqrs\\Types\\QueryFetcherInterfaceLmc\\Cqrs\\Handler\\QueryFetcher`@lmc_cqrs.query_fetcher`Lmc\\Cqrs\\Types\\CommandSenderInterfaceLmc\\Cqrs\\Handler\\CommandSender`@lmc_cqrs.command_sender`### Query Handlers

[](#query-handlers)

ServiceAliasTagPriorityEnabledLmc\\Cqrs\\Handler\\Handler\\GetCachedHandler--80if `cache` is enabledLmc\\Cqrs\\Handler\\Handler\\CallbackQueryHandler`@lmc_cqrs.query_handler.callback``lmc_cqrs.query_handler`50*always*Lmc\\Cqrs\\Http\\Handler\\HttpQueryHandler`@lmc_cqrs.query_handler.http``lmc_cqrs.query_handler`50if `http` extension is enabled### Send Command Handlers

[](#send-command-handlers)

ServiceAliasTagPriorityEnabledLmc\\Cqrs\\Handler\\Handler\\CallbackSendCommandHandler`@lmc_cqrs.send_command_handler.callback``lmc_cqrs.send_command_handler`50*always*Lmc\\Cqrs\\Http\\Handler\\HttpSendCommandHandler`@lmc_cqrs.send_command_handler.http``lmc_cqrs.send_command_handler`50if `http` extension is enabled### Response decoders

[](#response-decoders)

ServiceAliasTagPriorityEnabledLmc\\Cqrs\\Http\\Decoder\\HttpMessageResponseDecoder`@lmc_cqrs.response_decoder.http``lmc_cqrs.response_decoder`90if `http` extension is enabledLmc\\Cqrs\\Http\\Decoder\\StreamResponseDecoder`@lmc_cqrs.response_decoder.stream``lmc_cqrs.response_decoder`70if `http` extension is enabledLmc\\Cqrs\\Types\\Decoder\\JsonResponseDecoder`@lmc_cqrs.response_decoder.json``lmc_cqrs.response_decoder`60*always*### Profiler formatters

[](#profiler-formatters)

ServiceAliasTagPriorityEnabledLmc\\Cqrs\\Http\\Formatter\\HttpProfilerFormatter`@lmc_cqrs.profiler_formatter.http``lmc_cqrs.profiler_formatter`-1if `http` extension is enabledLmc\\Cqrs\\Types\\Formatter\\JsonProfilerFormatter-`lmc_cqrs.profiler_formatter`-1if `profiler` is enabledLmc\\Cqrs\\Bundle\\Service\\ErrorProfilerFormatter-`lmc_cqrs.profiler_formatter`-1if `profiler` is enabled### Other services

[](#other-services)

ClassAliasPurposeEnabledLmc\\Cqrs\\Bundle\\Controller\\CacheController-Controller for invalidating cache from a profilerif `profiler` is enabledLmc\\Cqrs\\Bundle\\Profiler\\CqrsDataCollector-Collects a data about Commands &amp; Queries for a profilerif `profiler` is enabledLmc\\Cqrs\\Handler\\ProfilerBag`@lmc_cqrs.profiler_bag`A collection of all ProfilerItems, it is a main source of data for a CqrsDataCollectorif `profiler` is enabled

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity27

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 100% 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 ~205 days

Recently: every ~237 days

Total

6

Last Release

803d ago

Major Versions

1.3.0 → 2.0.02022-05-06

PHP version history (3 changes)1.0.0PHP ^7.4

2.0.0PHP ^8.1

2.1.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/2bdf0b9957c08a48e70a52fce74fc4f1add30b12d442450d5e2b48854fc98b21?d=identicon)[MortalFlesh](/maintainers/MortalFlesh)

---

Top Contributors

[![MortalFlesh](https://avatars.githubusercontent.com/u/6317184?v=4)](https://github.com/MortalFlesh "MortalFlesh (22 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/lmc-cqrs-bundle/health.svg)

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

###  Alternatives

[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[simplesamlphp/simplesamlphp

A PHP implementation of a SAML 2.0 service provider and identity provider.

1.1k12.4M193](/packages/simplesamlphp-simplesamlphp)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)

PHPackages © 2026

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