QueryBus integration in Symfony.
QueryBusBundle can be installed using Composer:
composer require "gnugat/query-bus-bundle:~2.0"
We then need to register it in our application:
<?php
// File: app/AppKernel.php
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = array(
// ...
new Gnugat\QueryBusBundle\GnugatQueryBusBundle(),
);
// ...
}
// ...
}
Let's take the following entity:
<?php
// File: src/AppBundle/Entity/Article.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="article")
*/
class Article
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $title;
/**
* @ORM\Column(type="text")
*/
private $content;
public function __construct($title, $content)
{
$this->title = $title;
$this->content = $content;
}
public function getId()
{
return $this->id;
}
public function getTitle()
{
return $this->title;
}
public function getContent()
{
return $this->content;
}
}
In order to get one article by ID using QueryBundle, we have first to create an Interrogatory Message:
<?php
// File: src/AppBundle/QueryBus/GetArticle.php
namespace AppBundle\QueryBus;
class GetArticle
{
public $id;
public function __construct($id)
{
if (null === $id) {
throw new \InvalidArgumentException('Missing required argument: ID');
}
$this->id = $id;
}
}
We then have to create a QueryMatcher
:
<?php
// File: src/AppBundle/Marshaller/ArticleMarshaller.php
namespace AppBundle\QueryBus;
use AppBundle\Entity\Article;
use Doctrine\Common\Persistence\ObjectManager;
use Gnugat\QueryBus\QueryMatcher;
class GetArticleMatcher implements QueryMatcher
{
private $objectManager;
public function __construct(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
public function supports($query)
{
return $query instanceof GetArticle;
}
public function match($query)
{
$article = $this->objectManager->find('AppBundle:Article', $query->id);
if (null === $article) {
throw new \DomainException(sprintf('Could not find article for ID "%s"', $query->id));
}
return $article;
}
}
The next step is to define it as a service:
# File: app/config/services.yml
services:
app.get_article_matcher:
class: AppBundle\QueryBus\GetArticleMatcher
tags:
- { name: gnugat_query_bus.query_matcher }
Note: Thanks to the
gnugat_query_bus.query_matcher
tag, theGetArticleMatcher
will be registered in the maingnugat_query_bus.query_bus
service.
Finally we can request the article:
<?php
// File: src/AppBundle/Controller/ArticleController.php
namespace AppBundle\Controller;
use AppBundle\QueryBus\GetArticle;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
class ArtcileController extends Controller
{
/**
* @Route("/api/v1/articles/{id}")
* @Method({"GET"})
*/
public function viewAction($id)
{
$article = $this->get('gnugat_query_bus.query_bus')->match(new GetArticle($id));
return new JsonResponse(array(
'id' => $article->getId(),
'title' => $article->getTitle(),
'content' => $article->getContent(),
), 200);
}
}
You can see the current and past versions using one of the following:
- the
git tag
command - the releases page on Github
- the file listing the changes between versions
You can find more documentation at the following links: