gpslab/cqrs

Infrastructure for creating CQRS applications

v2.0.0 2020-01-22 08:45 UTC

This package is auto-updated.

Last update: 2020-11-22 10:57:22 UTC


README

Latest Stable Version Total Downloads Build Status Coverage Status Scrutinizer Code Quality SensioLabs Insight StyleCI License

CQRS

Infrastructure for creating CQRS applications.

CQRS base scheme

Installation

Pretty simple with Composer, run:

composer require gpslab/cqrs

Command

Simple usage commands

Commands, in the CQRS approach, are designed to change the data in the application.

For example, consider the procedure for renaming an article.

Create a command to rename:

use GpsLab\Component\Command\Command;

class RenameArticleCommand implements Command
{
    public $article_id;

    public $new_name = '';
}

Note

To simplify the filling of the command, you can use payload.

You can use any implementations of callable type as a command handler. We recommend using public methods of classes as handlers. For example we use Doctrine ORM.

use GpsLab\Component\Command\Command;
use Doctrine\ORM\EntityManagerInterface;

class RenameArticleHandler
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function handleRenameArticle(RenameArticleCommand $command): void
    {
        // get article by id
        $article = $this->em->getRepository(Article::class)->find($command->article_id);
        $article->rename($command->new_name);
    }
}

And now we register handler and handle command.

use GpsLab\Component\Command\Bus\HandlerLocatedCommandBus;
use GpsLab\Component\Command\Handler\Locator\DirectBindingCommandHandlerLocator;

// register command handler in handler locator
$handler = new RenameArticleHandler($em);
$locator = new DirectBindingCommandHandlerLocator();
$locator->registerHandler(RenameArticleCommand::class, [$handler, 'handleRenameArticle']);

// create bus with command handler locator
$bus = new HandlerLocatedCommandBus($locator);

// ...

// create rename article command
$command = new RenameArticleCommand();
$command->article_id = $article_id;
$command->new_name = $new_name;

// handle command
$bus->handle($command);

For the asynchronous handle a command you can use CommandQueue.

Note

To monitor the execution of commands, you can use middleware.

Query

Simple usage queries

Query, in the CQRS approach, are designed to get the data in the application.

For example, consider the procedure for get an article by identity.

Create a query:

use GpsLab\Component\Query\Query;

class ArticleByIdentityQuery implements Query
{
    public $article_id;
}

Note

To simplify the filling of the query, you can use payload.

You can use any implementations of callable type as a query handler. We recommend using public methods of classes as handlers. For example we use Doctrine ORM.

use GpsLab\Component\Query\Query;
use Doctrine\ORM\EntityManagerInterface;

class ArticleByIdentityHandler
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function handleArticleByIdentity(ArticleByIdentityQuery $query)
    {
        // get article by id
        return $this->em->getRepository(Article::class)->find($query->article_id);
    }
}

And now we register handler and handle query.

use GpsLab\Component\Query\Bus\HandlerLocatedQueryBus;
use GpsLab\Component\Query\Handler\Locator\DirectBindingQueryHandlerLocator;

// register query handler in handler locator
$handler = new ArticleByIdentityHandler($em);
$locator = new DirectBindingQueryHandlerLocator();
$locator->registerHandler(ArticleByIdentityQuery::class, [$handler, 'handleArticleByIdentity']);

// create bus with query handler locator
$bus = new HandlerLocatedQueryBus($locator);

// ...

// create find article query
$query = new ArticleByIdentityQuery();
$query->article_id = $article_id;

// handle query
$article = $bus->handle($query);

Note

To monitor the execution of commands, you can use middleware.

License

This bundle is under the MIT license. See the complete license in the file: LICENSE