Symfony Messenger is here, but your project is on Symfony 3.4, no problem! (part 1)

and it can be injected by Dependency Injection of Symfony (thanks autowiring ❤️) in another class or a controller action with:/** * @Route("/messenger") */class ListPostController{ public function __invoke(MessageBusInterface $bus): Response { // … }}but it is still like an empty box. Go to the next step for configuring messenger middlewares ????4) MiddlewaresThe component Messenger works with middlewares..It provides a few, but we will focus on the two main ones: MessageHandleMiddleware and SendMessageMiddlewareWith these, we can do some jobs in synchronous/asynchronous modes.Asynchronous mode, a scenario when the message A is captured by the SendMessageMiddleware and sent by one of its senders to other application or message queue:——————————————————————– A Bus —> SendMessageMiddleware —> HandleMessageMiddleware A —-—> – sender1 A – sender2: —> | Message `A` was sent by – senderN | sender22..Synchronous mode, a scenario when the message A is captured by the HandleMessageMiddleware and processed by one of its handlers:——————————————————————– A(1) A(3)Bus —-> SendMessageMiddleware —-> HandleMessageMiddleware A(2) A(4) —–> – sender1 | any —-—–> – handler1: <| – sender2 | sender – handler2 | – senderN | match, – handlerN | | message A | | returns back | ________________| selected handler takes the message3. You can have another scenario when the message A is captured by two middlewares.5) HandleMessageMiddlewareThis middleware has a stack of handlers and its job is to find a handler for a current message.Let’s configure it, put this code into messenger.yaml configuration file:messenger.middleware.handle_message: class: SymfonyComponentMessengerMiddlewareHandleMessageMiddleware abstract: true arguments: [[], true]note: the second argument true disables throwing an exception if one message doesn’t have a registered handler in the stack.Now, we must tell which middleware will be used by our super bus, do it with a DI parameter:parameters: my_super_bus.middleware: – { id: handle_message }note: this parameter will be used by the compiler pass (MessengerPass.php) and will be removed from the container after the compilation.Let’s test it with this basic implementation of the message:// Message classclass GetPostQuery{ private $limit; private $offset; public function __construct(int $offset = 0, int $limit = 10) { $this->offset = $offset; $this->limit = $limit; } public function getLimit(): int { return $this->limit; } public function getOffset(): int { return $this->offset; }}and handler:class GetPostHandler{ public function __invoke(GetPostQuery $query): array { return array_fill( $query->getOffset(), $query->getLimit(), [ 'title' => 'Post title', 'date' => new DateTime(), ] ); }}This handler returns a simple array the dimension of which depends on the $query properties..Note the type hint of the __invoke method..The compiler pass (MessengerPass.php) will register in the stack this handler for all instances of GetPostQuery message dispatched in the bus.Ah, don’t forget to define it as a tagged service:# services.yamlservices: # ….AppQueryGetPostHandler: tags: – { name: 'messenger.message_handler', bus: 'my_super_bus' }Cool, go test it with a simple controller:/** * @Route("/posts/list") */class PostListController extends AbstractController{ public function __invoke(MessageBusInterface $bus): Response { $envelop = $bus->dispatch(new GetPostQuery(0, 5)); /** @var HandledStamp $stamp */ if ($stamp = $envelop->last(HandledStamp::class)) { $posts = $stamp->getResult(); } return $this->render( 'post.html.twig', ['posts' => $posts ?? []] ); }}Here is what appears on my browser (with the template twig):In the next days, I will create the next part of this article to explain how to configure the asynchronous mode of Messenger with Symfony 3.4.If you encounter any issue with the component Messenger, please report it on GitHub.Any feedback?.Don’t hesitate to comment.. More details

Leave a Reply