In the previous post, we created a simple command bus. This time we are going to focus on query bus. Contrary to commands, queries return a value and don’t change the state of the system. The codebase for this post is available here.
Bus configuration
Let’s get started with the configuration of the bus. We don’t need to add any middleware this time.
// config/packages/messenger.yaml messenger: default_bus: command.bus buses: command.bus: middleware: - doctrine_transaction query.bus: ~
And restrict query handlers to be available only for the query bus.
// config/services.yaml services: // ... App\Query\Handler\: autoconfigure: false resource: '../src/Query/Handler' tags: [{ name: messenger.message_handler, bus: query.bus }]
Query and query handler
We want to retrieve all of the notes stored in a database so we don’t need to implement any parameters in our query.
// src/Query/GetAllNotes.php <?php namespace App\Query; class GetAllNotes { }
// src/Query/Handler/GetAllNotesHandler.php <?php namespace App\Query\Handler; use App\Query\GetAllNotes; use App\Repository\NoteRepository; use Symfony\Component\Messenger\Handler\MessageHandlerInterface; class GetAllNotesHandler implements MessageHandlerInterface { private $notes; public function __construct(NoteRepository $noteRepository) { $this->notes = $noteRepository; } public function __invoke(GetAllNotes $query) { return $this->notes->findAll(); } }
Now we can finally implement index action of IndexCotroller and make our application work.
// src/Controller/IndexController.php <?php namespace App\Controller; use App\Query\GetAllNotes; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Messenger\Stamp\HandledStamp; use Symfony\Component\Routing\Annotation\Route; class IndexController extends AbstractController { /** * @Route("/", name="index") */ public function index(MessageBusInterface $queryBus) { $envelope = $queryBus->dispatch(new GetAllNotes()); $handledStamp = $envelope->last(HandledStamp::class); $notes = $handledStamp->getResult(); return $this->render("index/index.html.twig", ["notes" => $notes]); } }
And that’s it! Now the home page of the application shows all notes stored in a database.
Summary
All code up to this point is available here. In the next post of the series, we are going to create an asynchronous event bus.