{"id":3453,"date":"2022-06-28T09:46:00","date_gmt":"2022-06-28T09:46:00","guid":{"rendered":"http:\/\/the-codest.localhost\/blog\/symfony-microservices-communication-part-i\/"},"modified":"2026-03-11T05:58:33","modified_gmt":"2026-03-11T05:58:33","slug":"komunikace-mikrosluzeb-v-symfony-cast-i-1","status":"publish","type":"post","link":"https:\/\/thecodest.co\/cs\/blog\/microservices-communication-in-symfony-part-i-1\/","title":{"rendered":"Symfony: Komunikace mikroslu\u017eeb \u010d\u00e1st I"},"content":{"rendered":"\n<p>Modern application architecture has forced developers to change the way of thinking about the communication between different components of IT systems. Once the matter was simpler &#8211; most systems were created as monolithic structures connected with each other by a network of business logic connections. Maintaining such dependencies in a <strong><a href=\"https:\/\/thecodest.co\/cs\/dictionary\/how-to-hire-a-php-developer\/\">PHP<\/a> <a href=\"https:\/\/thecodest.co\/cs\/dictionary\/why-do-projects-fail\/\">project<\/a><\/strong> was a huge challenge for <strong>PHP developers<\/strong>, and the growing popularity of <a href=\"https:\/\/thecodest.co\/cs\/dictionary\/saas-software-as-a-service\/\">SaaS<\/a> solutions and the huge increase in the popularity of <a href=\"https:\/\/thecodest.co\/cs\/dictionary\/what-is-elasticity-in-cloud-computing\/\">cloud<\/a> services caused that today we hear more and more about <a href=\"https:\/\/thecodest.co\/cs\/dictionary\/microservices\/\">microservices<\/a> and application modularity.<\/p>\n\n\n\n<p>Just how, by creating independent microservices, can we make them exchange information with each other?<\/p>\n\n\n\n<p>This article is the first in a series of posts on <strong>microservices communication in Symfony<\/strong> framework and it covers the most popular way &#8211; AMQP communication using RabbitMQ.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Goal<\/h2>\n\n\n\n<p>To create two independent applications and achieve communication between them using only Message Bus.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Concept<\/h2>\n\n\n\n<p>We have two, imaginary, independent applications:<br>* <code>app1<\/code>: which sends E-Mail and SMS notifications to employees<br>* <code>app2<\/code>: which allows you to manage employee&#8217;s work and assign them tasks.<\/p>\n\n\n\n<p>We want to create a modern and simple system whereby the assignment of work to an employee in <code>app2<\/code> will send a notification to the customer using <code>app1<\/code>. Despite appearances, this is very simple!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Preparation<\/h2>\n\n\n\n<p>For the purpose of this article, we will use the latest Symfony(version 6.1 at the time of writing) and the latest version of PHP (8.1). In a few very simple steps we will create a working local <a href=\"https:\/\/thecodest.co\/cs\/dictionary\/docker-developer\/\">Docker<\/a> environment with two microservices. All you need is:<br>* a working computer,<br>* installed Docker + <a href=\"https:\/\/docs.docker.com\/compose\/\">Docker Compose environment<\/a><br>* and a locally configured <a href=\"https:\/\/symfony.com\/download\">Symfony CLI<\/a> and some free time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Runtime environment<\/h2>\n\n\n\n<p>We will use Docker&#8217;s capabilities as an application virtualization and containerization tool. Let&#8217;s start by creating a directory tree, a framework for two <strong>Symfony applications<\/strong>, and describe the infrastructure of our environments using the <code>docker-compose.yml<\/code> file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"><code> cd ~\n mkdir microservices-in-symfony\n cd microservices-in-symfony\n symfony new app1\n symfony new app2\n touch docker-compose.yml<\/code><\/code><\/pre>\n\n\n\n<p>We have created two directories for two separate Symfony applications and created an empty <code>docker-compose.yml<\/code> file to launch our environment.<\/p>\n\n\n\n<p>Let&#8217;s add the following sections to the <code>docker-compose.yml<\/code> file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"yaml\" class=\"language-yaml\">version: '3.8'\n\nservices:\napp1:\ncontainername: app1\nbuild: app1\/.\nrestart: on-failure\nenvfile: app1\/.env\nenvironment:\nAPPNAME: app1\ntty: true\nstdinopen: true\n\napp2:\ncontainername: app2\nbuild: app2\/.\nrestart: on-failure\nenvfile: app2\/.env\nenvironment:\nAPPNAME: app2\ntty: true\nstdinopen: true\n\nrabbitmq:\ncontainername: rabbitmq\nimage: rabbitmq:management\nports:\n- 15672:15672\n- 5672:5672\nenvironment:\n- RABBITMQDEFAULTUSER=user\n- RABBITMQDEFAULT_PASS=password<\/code><\/pre>\n\n\n\n<p>Source <a href=\"https:\/\/thecodest.co\/cs\/dictionary\/what-is-code-refactoring\/\">code<\/a> available directly: <a href=\"https:\/\/github.com\/thecodest-co\/microservices-in-symfony\/blob\/main\/docker-compose.yml\">thecodest-co\/microservices-in-symfony\/blob\/main\/docker-compose.yml<\/a><\/p>\n\n\n\n<p>But wait, what happened here? For those unfamiliar with Docker, the above configuration file may seem enigmatic, however its purpose is very simple. Using Docker Compose we are building three &#8220;services&#8221;:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>app1: which is a container for the first Symfony application<\/li>\n\n\n\n<li>app2: which is the container for the second Symfony application<\/li>\n\n\n\n<li>rabbitmq: the RabbitMQ application image as a communication middleware layer<\/li>\n<\/ul>\n\n\n\n<p>For proper operation, we still need <code>Dockerfile<\/code> files which are the source to build the images. So let&#8217;s create them:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"><code> touch app1\/Dockerfile\n touch app2\/Dockerfile<\/code><\/code><\/pre>\n\n\n\n<p>Both files have exactly the same structure and look as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"docker\" class=\"language-docker\">FROM php:8.1\n\nCOPY --from=composer:latest \/usr\/bin\/composer \/usr\/local\/bin\/composer\nCOPY . \/app\/\nWORKDIR \/app\/\n\nADD https:\/\/github.com\/mlocati\/docker-php-extension-installer\/releases\/latest\/download\/install-php-extensions \/usr\/local\/bin\/\n\nRUN chmod +x \/usr\/local\/bin\/install-php-extensions &amp;&amp; sync &amp;&amp;\ninstall-php-extensions amqp\n\nRUN apt-get update\n&amp;&amp; apt-get install -y libzip-dev wget --no-install-recommends\n&amp;&amp; apt-get clean\n&amp;&amp; rm -rf \/var\/lib\/apt\/lists\/* \/tmp\/* \/var\/tmp\/*\n\nRUN docker-php-ext-install zip;\n\nCMD bash -c \"cd \/app &amp;&amp; composer install &amp;&amp; php -a\"<\/code><\/pre>\n\n\n\n<p>Source code available directly: <a href=\"https:\/\/github.com\/thecodest-co\/microservices-in-symfony\/blob\/main\/app1\/Dockerfile\">\/thecodest-co\/microservices-in-symfony\/blob\/main\/app1\/Dockerfile<\/a><\/p>\n\n\n\n<p>The above file is used by Docker Compose to build a container from a PHP 8.1 image with Composer and the AMQP extension installed. Additionally, it runs the PHP intepreter in append mode to keep the container running in the background.<\/p>\n\n\n\n<p>Your directory and file tree should now look as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"><code> .\n \u251c\u2500\u2500 app1\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 Dockerfile\n |       (...) # Symfony App Structure\n \u251c\u2500\u2500 app2\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 Dockerfile\n |       (...) # Symfony App Structure\n \u2514\u2500\u2500 docker-compose.yml<\/code><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">The first Symfony microservice<\/h2>\n\n\n\n<p>Let&#8217;s start with the <code>app1<\/code> directory and the first application.<br>In our example, it is an application that listens and consumes messages from the queue sent by <code>app2<\/code> as described in the requirements:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>assigning a job to a worker in <code>app2<\/code> will send a notification to the client<\/p>\n<\/blockquote>\n\n\n\n<p>Let&#8217;s start by adding the required libraries. AMQP is natively supported for the <code>symfony\/messenger<\/code> extension. We will additionally install <code>monolog\/monolog<\/code> to keep track of system logs for easier application behavior analysis.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"><code> cd app1\/\n symfony composer req amqp ampq-messenger monolog<\/code><\/code><\/pre>\n\n\n\n<p>After the installation, an additional file was added under <code>config\/packages\/messenger.yaml<\/code>. It is a configuration file for the Symfony Messenger component and we don&#8217;t need its <a href=\"https:\/\/symfony.com\/doc\/current\/messenger.html\">full configuration<\/a>.<br>Replace it with the YAML file below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"yaml\" class=\"language-yaml\">framework:\nmessenger:\n# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.\n# failure_transport: failed\n\n    transports:\n        # https:\/\/symfony.com\/doc\/current\/messenger.html#transport-configuration\n        external_messages:\n            dsn: '%env(MESSENGER_TRANSPORT_DSN)%'\n            options:\n                auto_setup: false\n                exchange:\n                    name: messages\n                    type: direct\n                    default_publish_routing_key: from_external\n                queues:\n                    messages:\n                        binding_keys: [from_external]<\/code><\/pre>\n\n\n\n<p>Source code available directly: <a href=\"https:\/\/github.com\/thecodest-co\/microservices-in-symfony\/blob\/main\/app1\/config\/packages\/messenger.yaml\">thecodest-co\/microservices-in-symfony\/blob\/main\/app1\/config\/packages\/messenger.yaml<\/a><\/p>\n\n\n\n<p>Symfony Messenger is used for synchronous and asynchronous communication in Symfony applications. It supports a variety of <strong>transports<\/strong>, or sources of truth of the transport layer. In our example, we use the AMQP extension that supports the RabbitMQ event queue system.<\/p>\n\n\n\n<p>The above configuration defines a new transport named <code>external_messages<\/code>, which references the <code>MESSENGER_TRANSPORT_DSN<\/code> environment variable and defines direct listening on the <code>messages<\/code> channel in Message Bus. At this point, also edit the <code>app1\/.env<\/code> file and add the appropriate transport address.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">\u201c`env\n\n(\u2026)\nMESSENGERTRANSPORTDSN=amqp:\/\/user:password@rabbitmq:5672\/%2f\/messages\n(\u2026)\n\u201c\nAfter preparing the application framework and configuring the libraries, it is time to implement the business logic. We know that our application must respond to the assignment of a job to a worker. We also know that assigning a job in theapp2system changes the status of the job. So let's create a model that mimics the status change and save it in theapp1\/Message\/StatusUpdate.php` path:<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/174621467-08418929-2b37-4398-a5bb-6cbbdf4493cb.png\" alt=\"image\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\"> {\npublic function __construct(protected string $status){}\n\npublic function getStatus(): string\n{\n    return $this->status;\n}\n\n}<\/code><\/pre>\n\n\n\n<p>Source code available directly: <a href=\"https:\/\/github.com\/thecodest-co\/microservices-in-symfony\/blob\/main\/app1\/src\/Message\/StatusUpdate.php\">\/thecodest-co\/microservices-in-symfony\/blob\/main\/app1\/src\/Message\/StatusUpdate.php<\/a><\/p>\n\n\n\n<p>We still need a class that will implement the business logic when our <a href=\"https:\/\/thecodest.co\/cs\/blog\/exploring-microservice-based-frontend-architecture\/\">microservice<\/a> receives the above event from the queue. So let&#8217;s create a <a href=\"https:\/\/symfony.com\/doc\/current\/messenger\/handler_results.html\">Message Handler<\/a> in the <code>app1\/Handler\/StatusUpdateHandler.php<\/code> path:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/174621830-9e495a4d-f13e-4565-8485-bfcd50ec8b4a.png\" alt=\"image\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\"> use PsrLogLoggerInterface;\nuse SymfonyComponentMessengerAttributeAsMessageHandler;\n\n[AsMessageHandler]\n\nclass StatusUpdateHandler\n{\npublic function __construct(\nprotected LoggerInterface $logger,\n) {}\n\npublic function __invoke(StatusUpdate $statusUpdate): void\n{\n    $statusDescription = $statusUpdate->getStatus();\n\n    $this->logger->warning('APP1: {STATUS_UPDATE} - '.$statusDescription);\n\n    \/\/ the rest of business logic, i.e. sending email to user\n    \/\/ $this->emailService->email()\n}\n\n}<\/code><\/pre>\n\n\n\n<p>Source code available directly: <a href=\"https:\/\/github.com\/thecodest-co\/microservices-in-symfony\/blob\/main\/app1\/src\/Handler\/StatusUpdateHandler.php\">\/thecodest-co\/microservices-in-symfony\/blob\/main\/app1\/src\/Handler\/StatusUpdateHandler.php<\/a><\/p>\n\n\n\n<p><strong>PHP<\/strong> attributes make things much easier and mean that in this particular case we don&#8217;t have to worry about autowiring or service declaration. Our microservice for handling domain events is ready, it&#8217;s time to get down to the second application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Second Symfony microservice<\/h2>\n\n\n\n<p>We will take a look at the <code>app2<\/code> directory and the second <strong>Symfony application<\/strong>. Our idea is to send a message to the queue when a worker is assigned a task in the system. So let&#8217;s do a quick configuration of AMQP and get our second microservice to start publishing <code>StatusUpdate<\/code> events to the Message Bus.<\/p>\n\n\n\n<p>Installing the libraries is exactly the same as for the first application.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"><code> cd ..\n cd app2\/\n symfony composer req amqp ampq-messenger monolog<\/code><\/code><\/pre>\n\n\n\n<p>Let&#8217;s make sure that the <code>app2\/.env<\/code> file contains a valid DSN entry for RabbitMQ:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\"><code>(...)\n MESSENGER_TRANSPORT_DSN=amqp:\/\/user:password@rabbitmq:5672\/%2f\/messages\n (...)<\/code><\/code><\/pre>\n\n\n\n<p>All that remains is to configure Symfony Messenger in the <code>app2\/config\/packages\/messenger.yaml<\/code> file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"yaml\" class=\"language-yaml\">framework:\nmessenger:\n# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.\n# failure_transport: failed\n\n    transports:\n        # https:\/\/symfony.com\/doc\/current\/messenger.html#transport-configuration\n        async:\n            dsn: '%env(MESSENGER_TRANSPORT_DSN)%'\n\n    routing:\n        # Route your messages to the transports\n        'AppMessageStatusUpdate': async<\/code><\/pre>\n\n\n\n<p>As you can see, this time the transport definition points directly to <code>async<\/code> and defines routing in the form of sending our <code>StatusUpdate<\/code> message to the configured DSN. This is the only area of configuration, all that is left is to create the logic and implementation layer of the AMQP queue. For this we will create the twin <code>StatusUpdateHandler<\/code> and <code>StatusUpdate<\/code> classes in <code>app2<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/174622496-80d71c52-1f33-47bf-82d3-bac4d83525dc.png\" alt=\"image\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\"> use PsrLogLoggerInterface;\nuse SymfonyComponentMessengerAttributeAsMessageHandler;\n\n[AsMessageHandler]\n\nclass StatusUpdateHandler\n{\npublic function __construct(\nprivate readonly LoggerInterface $logger,\n) {}\n\npublic function __invoke(StatusUpdate $statusUpdate): void\n{\n    $statusDescription = $statusUpdate->getStatus();\n\n    $this->logger->warning('APP2: {STATUS_UPDATE} - '.$statusDescription);\n\n    ## business logic, i.e. sending internal notification or queueing some other systems\n}\n\n}<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/174621467-08418929-2b37-4398-a5bb-6cbbdf4493cb.png\" alt=\"image\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\"> {\npublic function __construct(protected string $status){}\n\npublic function getStatus(): string\n{\n    return $this->status;\n}\n\n}<\/code><\/pre>\n\n\n\n<p><br>Source code available directly: <a href=\"https:\/\/github.com\/thecodest-co\/microservices-in-symfony\/blob\/main\/app2\/src\/Message\/StatusUpdate.php\">\/thecodest-co\/microservices-in-symfony\/blob\/main\/app2\/src\/Message\/StatusUpdate.php<\/a><\/p>\n\n\n\n<p>Finally, all that has to be done is to create a way to send a message to the Message Bus. We will create a simple <a href=\"https:\/\/symfony.com\/doc\/current\/console.html\">Symfony Command<\/a> for this:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/174623304-2fd696df-28b7-4946-ad2c-671bb8d589f3.png\" alt=\"image\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">use SymfonyComponentConsoleAttributeAsCommand;\nuse SymfonyComponentConsoleCommandCommand;\nuse SymfonyComponentConsoleInputInputInterface;\nuse SymfonyComponentConsoleOutputOutputInterface;\nuse SymfonyComponentMessengerMessageBusInterface;\n\n[AsCommand(\n\nname: \"app:send\"\n\n)]\nclass SendStatusCommand extends Command\n{\npublic function construct(private readonly MessageBusInterface $messageBus, string $name = null)\n{\nparent::construct($name);\n}\n\nprotected function execute(InputInterface $input, OutputInterface $output): int\n{\n    $status = \"Worker X assigned to Y\";\n\n    $this->messageBus->dispatch(\n        message: new StatusUpdate($status)\n    );\n\n    return Command::SUCCESS;\n}\n\n}<\/code><\/pre>\n\n\n\n<p>Thanks to <a href=\"https:\/\/symfony.com\/doc\/current\/components\/dependency_injection.html\">Dependency Injection<\/a> we can use an instance of <code>MessageBusInterface<\/code> in our Command and send a <code>StatusUpdate<\/code> message via the <code>dispatch()<\/code> method to our queue. Additionally, we also use PHP Attributes here.<\/p>\n\n\n\n<p>That&#8217;s it &#8211; all that&#8217;s left is to run our Docker Compose environment and see how our applications behave.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running the environment and testing<\/h2>\n\n\n\n<p>With Docker Compose the containers with our two applications will be built and run as separate instances, the only middleware layer will be the <code>rabbitmq<\/code> container and our Message Bus implementation.<\/p>\n\n\n\n<p>From the root directory of the project, let&#8217;s run the following commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"><code>cd ..\/ # make sure you're in main directory\n docker-compose up --build -d<\/code><\/code><\/pre>\n\n\n\n<p>This command can take some time, as it builts two separate containers with PHP 8.1 + AMQP and pulls RabbitMQ image. Be patient. After images are built you can fire our Command from <code>app2<\/code> and send some messages on a queue.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"><code> docker exec -it app2 php bin\/console app:send<\/code><\/code><\/pre>\n\n\n\n<p>You can do it as many times as you can. As long as there&#8217;s no <strong><em>consumer<\/em><\/strong> your messages will not be processed. As soon as you fire up the <code>app1<\/code> and consume all the messages they&#8217;ll show on your screen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"><code><code>docker exec -it app1 php bin\/console messenger:consume -vv external_messages<\/code><\/code><\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/174612800-37393c80-bc4a-47f8-9448-2c64173ebddb.png\" alt=\"image\"\/><\/figure>\n\n\n\n<p>The complete <a href=\"https:\/\/github.com\/thecodest-co\/microservices-in-symfony\">source code<\/a> along with the README can be found in our public repository <a href=\"https:\/\/github.com\/thecodest-co\/\">The Codest Github<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>Symfony with its libraries and tools allows for a fast and efficient approach to developing modern <strong><a href=\"https:\/\/thecodest.co\/cs\/blog\/find-your-ideal-stack-for-web-development\/\">web<\/a> applications<\/strong>. With a few commands and a few lines of code we are able to create a modern communication system between applications. Symfony, like <strong>PHP<\/strong>, is ideal for <strong>developing web applications<\/strong> and thanks to its ecosystem and ease of implementation this ecosystem achieves some of the best time-to-market indicators.<\/p>\n\n\n\n<p>However, fast does not always mean good &#8211; in the example above we presented the simplest and fastest way of communication. What the more inquisitive will certainly notice that there is a lack of disconnection of domain events outside the application layer &#8211; in the current version they are duplicated, and there is no full support for <code>Envelope<\/code>, among others there is no <code>Stamps<\/code>. For those and others, I invite you to read Part II, where we&#8217;ll cover the topic of unifying the domain structure of Symfony applications in a microservices environment, and discuss the second popular microservices communication method &#8211; this time synchronous, based on the REST <a href=\"https:\/\/thecodest.co\/cs\/blog\/compare-staff-augmentation-firms-that-excel-in-api-team-staffing-for-financial-technology-projects\/\">API<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/thecodest.co\/contact\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/interested_in_cooperation_.png\" alt=\"cooperation banner\"\/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>P\u0159e\u010dt\u011bte si prvn\u00ed d\u00edl seri\u00e1lu PHP v\u011bnovan\u00fd komunikaci mikroslu\u017eeb ve frameworku Symfony a nejobl\u00edben\u011bj\u0161\u00edmu zp\u016fsobu - komunikaci AMQP pomoc\u00ed RabbitMQ.<\/p>","protected":false},"author":2,"featured_media":3454,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[8],"tags":[],"class_list":["post-3453","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Symfony: Microservices Communication part I - The Codest<\/title>\n<meta name=\"description\" content=\"Read the first part of our PHP series devoted to microservices communication in Symfony framework and the most popular way.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/thecodest.co\/cs\/blog\/komunikace-mikrosluzeb-v-symfony-cast-i-1\/\" \/>\n<meta property=\"og:locale\" content=\"cs_CZ\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Symfony: Microservices Communication part I\" \/>\n<meta property=\"og:description\" content=\"Read the first part of our PHP series devoted to microservices communication in Symfony framework and the most popular way.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/thecodest.co\/cs\/blog\/komunikace-mikrosluzeb-v-symfony-cast-i-1\/\" \/>\n<meta property=\"og:site_name\" content=\"The Codest\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-28T09:46:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-11T05:58:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/microservices_communication_in_symfony.png\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"540\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"thecodest\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"thecodest\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/\"},\"author\":{\"name\":\"thecodest\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/person\\\/7e3fe41dfa4f4e41a7baad4c6e0d4f76\"},\"headline\":\"Symfony: Microservices Communication part I\",\"datePublished\":\"2022-06-28T09:46:00+00:00\",\"dateModified\":\"2026-03-11T05:58:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/\"},\"wordCount\":1375,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/microservices_communication_in_symfony.png\",\"articleSection\":[\"Software Development\"],\"inLanguage\":\"cs-CZ\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/\",\"url\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/\",\"name\":\"Symfony: Microservices Communication part I - The Codest\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/microservices_communication_in_symfony.png\",\"datePublished\":\"2022-06-28T09:46:00+00:00\",\"dateModified\":\"2026-03-11T05:58:33+00:00\",\"description\":\"Read the first part of our PHP series devoted to microservices communication in Symfony framework and the most popular way.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/#breadcrumb\"},\"inLanguage\":\"cs-CZ\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"cs-CZ\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/#primaryimage\",\"url\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/microservices_communication_in_symfony.png\",\"contentUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/microservices_communication_in_symfony.png\",\"width\":960,\"height\":540},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/microservices-communication-in-symfony-part-i-1\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/thecodest.co\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Symfony: Microservices Communication part I\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#website\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"name\":\"The Codest\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/thecodest.co\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"cs-CZ\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\",\"name\":\"The Codest\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"cs-CZ\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/03\\\/thecodest-logo.svg\",\"contentUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/03\\\/thecodest-logo.svg\",\"width\":144,\"height\":36,\"caption\":\"The Codest\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/pl.linkedin.com\\\/company\\\/codest\",\"https:\\\/\\\/clutch.co\\\/profile\\\/codest\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/person\\\/7e3fe41dfa4f4e41a7baad4c6e0d4f76\",\"name\":\"thecodest\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"cs-CZ\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"caption\":\"thecodest\"},\"url\":\"https:\\\/\\\/thecodest.co\\\/cs\\\/author\\\/thecodest\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Symfony: The Codest: Komunikace mikroslu\u017eeb - \u010d\u00e1st I.","description":"P\u0159e\u010dt\u011bte si prvn\u00ed d\u00edl seri\u00e1lu PHP v\u011bnovan\u00fd komunikaci mikroslu\u017eeb ve frameworku Symfony a nejobl\u00edben\u011bj\u0161\u00edmu zp\u016fsobu.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/thecodest.co\/cs\/blog\/komunikace-mikrosluzeb-v-symfony-cast-i-1\/","og_locale":"cs_CZ","og_type":"article","og_title":"Symfony: Microservices Communication part I","og_description":"Read the first part of our PHP series devoted to microservices communication in Symfony framework and the most popular way.","og_url":"https:\/\/thecodest.co\/cs\/blog\/komunikace-mikrosluzeb-v-symfony-cast-i-1\/","og_site_name":"The Codest","article_published_time":"2022-06-28T09:46:00+00:00","article_modified_time":"2026-03-11T05:58:33+00:00","og_image":[{"width":960,"height":540,"url":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/microservices_communication_in_symfony.png","type":"image\/png"}],"author":"thecodest","twitter_card":"summary_large_image","twitter_misc":{"Written by":"thecodest","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/#article","isPartOf":{"@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/"},"author":{"name":"thecodest","@id":"https:\/\/thecodest.co\/#\/schema\/person\/7e3fe41dfa4f4e41a7baad4c6e0d4f76"},"headline":"Symfony: Microservices Communication part I","datePublished":"2022-06-28T09:46:00+00:00","dateModified":"2026-03-11T05:58:33+00:00","mainEntityOfPage":{"@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/"},"wordCount":1375,"commentCount":0,"publisher":{"@id":"https:\/\/thecodest.co\/#organization"},"image":{"@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/#primaryimage"},"thumbnailUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/microservices_communication_in_symfony.png","articleSection":["Software Development"],"inLanguage":"cs-CZ","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/","url":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/","name":"Symfony: The Codest: Komunikace mikroslu\u017eeb - \u010d\u00e1st I.","isPartOf":{"@id":"https:\/\/thecodest.co\/#website"},"primaryImageOfPage":{"@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/#primaryimage"},"image":{"@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/#primaryimage"},"thumbnailUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/microservices_communication_in_symfony.png","datePublished":"2022-06-28T09:46:00+00:00","dateModified":"2026-03-11T05:58:33+00:00","description":"P\u0159e\u010dt\u011bte si prvn\u00ed d\u00edl seri\u00e1lu PHP v\u011bnovan\u00fd komunikaci mikroslu\u017eeb ve frameworku Symfony a nejobl\u00edben\u011bj\u0161\u00edmu zp\u016fsobu.","breadcrumb":{"@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/#breadcrumb"},"inLanguage":"cs-CZ","potentialAction":[{"@type":"ReadAction","target":["https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/"]}]},{"@type":"ImageObject","inLanguage":"cs-CZ","@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/#primaryimage","url":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/microservices_communication_in_symfony.png","contentUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/microservices_communication_in_symfony.png","width":960,"height":540},{"@type":"BreadcrumbList","@id":"https:\/\/thecodest.co\/blog\/microservices-communication-in-symfony-part-i-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/thecodest.co\/"},{"@type":"ListItem","position":2,"name":"Symfony: Microservices Communication part I"}]},{"@type":"WebSite","@id":"https:\/\/thecodest.co\/#website","url":"https:\/\/thecodest.co\/","name":"The Codest","description":"","publisher":{"@id":"https:\/\/thecodest.co\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/thecodest.co\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"cs-CZ"},{"@type":"Organization","@id":"https:\/\/thecodest.co\/#organization","name":"The Codest","url":"https:\/\/thecodest.co\/","logo":{"@type":"ImageObject","inLanguage":"cs-CZ","@id":"https:\/\/thecodest.co\/#\/schema\/logo\/image\/","url":"https:\/\/thecodest.co\/app\/uploads\/2024\/03\/thecodest-logo.svg","contentUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/03\/thecodest-logo.svg","width":144,"height":36,"caption":"The Codest"},"image":{"@id":"https:\/\/thecodest.co\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/pl.linkedin.com\/company\/codest","https:\/\/clutch.co\/profile\/codest"]},{"@type":"Person","@id":"https:\/\/thecodest.co\/#\/schema\/person\/7e3fe41dfa4f4e41a7baad4c6e0d4f76","name":"thecodest","image":{"@type":"ImageObject","inLanguage":"cs-CZ","@id":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","caption":"thecodest"},"url":"https:\/\/thecodest.co\/cs\/author\/thecodest\/"}]}},"_links":{"self":[{"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/posts\/3453","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/comments?post=3453"}],"version-history":[{"count":11,"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/posts\/3453\/revisions"}],"predecessor-version":[{"id":8363,"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/posts\/3453\/revisions\/8363"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/media\/3454"}],"wp:attachment":[{"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/media?parent=3453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/categories?post=3453"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thecodest.co\/cs\/wp-json\/wp\/v2\/tags?post=3453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}