11How to Create Multiple Symfony Applications with a Single Kernel
22================================================================
33
4- In most Symfony applications, incoming requests are processed by the front controller at ``public/index.php ``, which
5- instantiates the ``src/Kernel.php `` class to create the application kernel. This kernel loads the bundles, configurations,
6- and handles the request to generate the response.
7-
8- The current implementation of the Kernel class serves as a convenient default for a single application. However, it can
9- also manage multiple applications. While the Kernel typically runs the same application with different configurations
10- based on various :ref: `environments <configuration-environments >` , it can be adapted to run different applications with
11- specific bundles and configurations.
12-
13- These are some of the common use cases for creating multiple applications with a single Kernel:
14-
15- * An application that defines an API can be divided into two segments to improve performance. The first segment serves
16- the regular web application, while the second segment exclusively responds to API requests. This approach requires
17- loading fewer bundles and enabling fewer features for the second part, thus optimizing performance;
18- * A highly sensitive application could be divided into two parts for enhanced security. The first part would only load
19- routes corresponding to the publicly exposed sections of the application. The second part would load the remainder of
20- the application, with its access safeguarded by the web server;
21- * A monolithic application could be gradually transformed into a more distributed architecture, such as micro-services.
22- This approach allows for a seamless migration of a large application while still sharing common configurations and
23- components.
4+ In Symfony applications, incoming requests are usually processed by the front
5+ controller at ``public/index.php ``, which instantiates the ``src/Kernel.php ``
6+ class to create the application kernel. This kernel loads the bundles, the
7+ configuration, and handles the request to generate the response.
8+
9+ The current implementation of the Kernel class serves as a convenient default
10+ for a single application. However, it can also manage multiple applications.
11+ While the Kernel typically runs the same application with different
12+ configurations based on various :ref: `environments <configuration-environments >`,
13+ it can be adapted to run different applications with specific bundles and configuration.
14+
15+ These are some of the common use cases for creating multiple applications with a
16+ single Kernel:
17+
18+ * An application that defines an API can be divided into two segments to improve
19+ performance. The first segment serves the regular web application, while the
20+ second segment exclusively responds to API requests. This approach requires
21+ loading fewer bundles and enabling fewer features for the second part, thus
22+ optimizing performance;
23+ * A highly sensitive application could be divided into two parts for enhanced
24+ security. The first part would only load routes corresponding to the publicly
25+ exposed sections of the application. The second part would load the remainder
26+ of the application, with its access safeguarded by the web server;
27+ * A monolithic application could be gradually transformed into a more
28+ distributed architecture, such as micro-services. This approach allows for a
29+ seamless migration of a large application while still sharing common
30+ configurations and components.
2431
2532Turning a Single Application into Multiple Applications
2633-------------------------------------------------------
2734
28- Let's explore the steps required to convert a single application into a new one that supports multiple applications:
35+ These are the steps required to convert a single application into a new one that
36+ supports multiple applications:
2937
30381. Create a new application;
31392. Update the Kernel class to support multiple applications;
32403. Add a new ``APP_ID `` environment variable;
33414. Update the front controllers.
3442
35- The following example shows how to create a new application for the API of a new Symfony project.
43+ The following example shows how to create a new application for the API of a new
44+ Symfony project.
3645
3746Step 1) Create a new Application
3847~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3948
40- In this example, we will use the `Shared Kernel `_ pattern, where, although all applications maintain an isolated context,
41- they can share common bundles, configurations, and code if desired. The optimal approach will depend on your specific
42- needs and requirements, so it's up to you to decide which best suits your project.
49+ This example follows the `Shared Kernel `_ pattern: all applications maintain an
50+ isolated context, but they can share common bundles, configuration, and code if
51+ desired. The optimal approach will depend on your specific needs and
52+ requirements, so it's up to you to decide which best suits your project.
4353
44- First, let's create a new ``apps `` directory at the root of your project, which will hold all the necessary applications.
45- Each application will follow a simplified directory structure like the one described in :ref: `Symfony Best Practice </best_practices >`:
54+ First, create a new ``apps `` directory at the root of your project, which will
55+ hold all the necessary applications. Each application will follow a simplified
56+ directory structure like the one described in :ref: `Symfony Best Practice </best_practices >`:
4657
4758.. code-block :: text
4859
@@ -64,17 +75,20 @@ Each application will follow a simplified directory structure like the one descr
6475
6576 .. note ::
6677
67- Note that the ``config/ `` and ``src/ `` directories at the root of the project will represent the shared context among
68- all applications within the ``apps/ `` directory. Therefore, you should carefully consider what is common and what
69- should be placed in the specific application.
78+ Note that the ``config/ `` and ``src/ `` directories at the root of the
79+ project will represent the shared context among all applications within the
80+ ``apps/ `` directory. Therefore, you should carefully consider what is
81+ common and what should be placed in the specific application.
7082
7183.. tip ::
7284
73- You might also consider renaming the namespace for the shared context, from ``App `` to ``Shared ``, as it will make it
74- easier to distinguish and provide clearer meaning to this context.
85+ You might also consider renaming the namespace for the shared context, from
86+ ``App `` to ``Shared ``, as it will make it easier to distinguish and provide
87+ clearer meaning to this context.
7588
76- Since the new ``apps/api/src/ `` directory will host the PHP code related to the API, we need to update the ``composer.json ``
77- file to include it in the autoload section:
89+ Since the new ``apps/api/src/ `` directory will host the PHP code related to the
90+ API, you have to update the ``composer.json `` file to include it in the autoload
91+ section:
7892
7993.. code-block :: json
8094
@@ -87,15 +101,18 @@ file to include it in the autoload section:
87101 }
88102 }
89103
90- Additionally, don't forget to run `composer dump-autoload ` to generate the autoload files.
104+ Additionally, don't forget to run ``composer dump-autoload `` to generate the
105+ autoload files.
91106
92107Step 2) Update the Kernel class to support Multiple Applications
93108~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
94109
95- Since we aim to support multiple applications, we will add a new property ``string $id `` to the Kernel to identify the
96- application being loaded. This property will also allow us to split the cache, logs, and configuration files in order to
97- avoid collisions with other applications. Moreover, it contributes to performance optimization, as each application will
98- load only the required resources::
110+ Since there will be multiple applications, it's better to add a new property
111+ ``string $id `` to the Kernel to identify the application being loaded. This
112+ property will also allow you to split the cache, logs, and configuration files
113+ in order to avoid collisions with other applications. Moreover, it contributes
114+ to performance optimization, as each application will load only the required
115+ resources::
99116
100117 // src/Kernel.php
101118 namespace Shared;
@@ -193,14 +210,16 @@ load only the required resources::
193210 }
194211 }
195212
196- In this example, we reuse the default implementation to import configuration and routes based on a given configuration
197- directory. As we saw earlier, this approach will import both shared and app-specific resources.
213+ This example reuses the default implementation to import the configuration and
214+ routes based on a given configuration directory. As shown earlier, this
215+ approach will import both the shared and the app-specific resources.
198216
199217Step 3) Add a new APP_ID environment variable
200218~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
201219
202- Now, let's introduce a new environment variable that identifies the current application. This new variable can be added
203- to the ``.env `` file to provide a default value, but it should typically be added to your web server configuration.
220+ Next, define a new environment variable that identifies the current application.
221+ This new variable can be added to the ``.env `` file to provide a default value,
222+ but it should typically be added to your web server configuration.
204223
205224.. code-block :: bash
206225
@@ -209,14 +228,17 @@ to the ``.env`` file to provide a default value, but it should typically be adde
209228
210229 .. caution ::
211230
212- The value of this variable must match the application directory within ``apps/ `` as it is used in the Kernel to load
213- the specific application configuration.
231+ The value of this variable must match the application directory within
232+ ``apps/ `` as it is used in the Kernel to load the specific application
233+ configuration.
214234
215235Step 4) Update the Front Controllers
216236~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
217237
218- In this final step, we will update the front controllers ``public/index.php `` and ``bin/console `` to pass the value of
219- the ``APP_ID `` variable to the Kernel instance. This will allow the Kernel to load and run the specified application::
238+ In this final step, update the front controllers ``public/index.php `` and
239+ ``bin/console `` to pass the value of the ``APP_ID `` variable to the Kernel
240+ instance. This will allow the Kernel to load and run the specified
241+ application::
220242
221243 // public/index.php
222244 use Shared\Kernel;
@@ -226,11 +248,12 @@ the ``APP_ID`` variable to the Kernel instance. This will allow the Kernel to lo
226248 return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG'], $context['APP_ID']);
227249 };
228250
229- Similar to configuring the required ``APP_ENV `` and ``APP_DEBUG `` values, the third argument of the Kernel constructor
230- is now also necessary to setting the application ID, which is derived from an external configuration.
251+ Similar to configuring the required ``APP_ENV `` and ``APP_DEBUG `` values, the
252+ third argument of the Kernel constructor is now also necessary to set the
253+ application ID, which is derived from an external configuration.
231254
232- For the second front controller, we will define a new console option to allow passing the application ID we want to run
233- under CLI context::
255+ For the second front controller, define a new console option to allow passing
256+ the application ID to run under CLI context::
234257
235258 // bin/console
236259 use Shared\Kernel;
@@ -252,8 +275,9 @@ That's it!
252275Executing Commands
253276------------------
254277
255- The ``bin/console `` script, which is used to run Symfony commands, always uses the ``Kernel `` class to build the
256- application and load the commands. If you need to run console commands for a specific application, you can provide the
278+ The ``bin/console `` script, which is used to run Symfony commands, always uses
279+ the ``Kernel `` class to build the application and load the commands. If you
280+ need to run console commands for a specific application, you can provide the
257281``--id `` option along with the appropriate identity value:
258282
259283.. code-block :: terminal
@@ -266,8 +290,9 @@ application and load the commands. If you need to run console commands for a spe
266290 export APP_ID=api
267291 php bin/console cache:clear
268292
269- You might want to update the composer auto-scripts section to run multiple commands simultaneously. In this example,
270- we assume you have a second application for managing the configuration (admin):
293+ You might want to update the composer auto-scripts section to run multiple
294+ commands simultaneously. This example shows the commands of two different
295+ applications called ``api `` and ``admin ``:
271296
272297.. code-block :: json
273298
@@ -282,19 +307,23 @@ we assume you have a second application for managing the configuration (admin):
282307 }
283308 }
284309
285- Then, run `composer auto-scripts ` to test it!
310+ Then, run `` composer auto-scripts ` ` to test it!
286311
287312.. note ::
288313
289- The commands available for each console script (e.g. ``bin/console -iapi `` and ``bin/console -iadmin ``) can differ
290- because they depend on the bundles enabled for each application, which could be different.
314+ The commands available for each console script (e.g. ``bin/console -iapi ``
315+ and ``bin/console -iadmin ``) can differ because they depend on the bundles
316+ enabled for each application, which could be different.
291317
292318Rendering Templates
293319-------------------
294320
295- Let's assume there is now another app called ``admin ``. If you follow the :ref: `Symfony Best Practices </best_practices >`, the shared Kernel
296- templates will be located in the ``templates/ `` directory at the project's root. For admin-specific templates, you can
297- create a new directory ``apps/admin/templates/ `` which you will need to manually configure under the Admin application:
321+ Let's consider that you need to create another app called ``admin ``. If you
322+ follow the :ref: `Symfony Best Practices </best_practices >`, the shared Kernel
323+ templates will be located in the ``templates/ `` directory at the project's root.
324+ For admin-specific templates, you can create a new directory
325+ ``apps/admin/templates/ `` which you will need to manually configure under the
326+ Admin application:
298327
299328.. code-block :: yaml
300329
@@ -303,15 +332,18 @@ create a new directory ``apps/admin/templates/`` which you will need to manually
303332 paths :
304333 ' %kernel.project_dir%/apps/admin/templates ' : Admin
305334
306- Then, use this Twig namespace to reference any template within the Admin application only, for example ``@Admin/form/fields.html.twig ``.
335+ Then, use this Twig namespace to reference any template within the Admin
336+ application only, for example ``@Admin/form/fields.html.twig ``.
307337
308338Running Tests
309339-------------
310340
311- In Symfony applications, functional tests typically extend from the :class: `Symfony\\ Bundle\\ FrameworkBundle\\ Test\\ WebTestCase `
312- class by default. Within its parent class, ``KernelTestCase ``, there is a method called ``createKernel() `` that attempts to
313- create the kernel responsible for running the application during tests. However, the current logic of this method doesn't
314- include our new application ID argument, so we need to make an update::
341+ In Symfony applications, functional tests typically extend from
342+ the :class: `Symfony\\ Bundle\\ FrameworkBundle\\ Test\\ WebTestCase ` class by
343+ default. Within its parent class, ``KernelTestCase ``, there is a method called
344+ ``createKernel() `` that attempts to create the kernel responsible for running
345+ the application during tests. However, the current logic of this method doesn't
346+ include the new application ID argument, so you need to update it::
315347
316348 // apps/api/tests/ApiTestCase.php
317349 namespace Api\Tests;
@@ -333,11 +365,12 @@ include our new application ID argument, so we need to make an update::
333365
334366.. note ::
335367
336- Keep in mind that we will set a fixed application ID value in this instance, as the specific test cases extending
337- from ``ApiTestCase `` will focus solely on the ``api `` tests.
368+ This examples uses a hardcoded application ID value because the tests
369+ extending this ``ApiTestCase `` class will focus solely on the ``api `` tests.
338370
339- In this situation, we have created a ``tests/ `` directory inside the ``apps/api/ `` application. As a result, we need to
340- inform both the ``composer.json `` file and our ``phpunit.xml `` configuration about its existence:
371+ Now, create a ``tests/ `` directory inside the ``apps/api/ `` application. Then,
372+ update both the ``composer.json `` file and ``phpunit.xml `` configuration about
373+ its existence:
341374
342375.. code-block :: json
343376
@@ -368,8 +401,9 @@ And, here is the update needed for the ``phpunit.xml`` file:
368401 Adding more Applications
369402------------------------
370403
371- Now you can begin adding more applications as needed, such as an ``admin `` application to manage the project's
372- configuration and permissions. To do that, you will have to repeat the step 1 only:
404+ Now you can begin adding more applications as needed, such as an ``admin ``
405+ application to manage the project's configuration and permissions. To do that,
406+ you will have to repeat the step 1 only:
373407
374408.. code-block :: text
375409
@@ -384,6 +418,7 @@ configuration and permissions. To do that, you will have to repeat the step 1 on
384418 │ └─ api/
385419 │ └─ ...
386420
387- Additionally, you might need to update your web server configuration to set the ``APP_ID=admin `` under a different domain.
421+ Additionally, you might need to update your web server configuration to set the
422+ ``APP_ID=admin `` under a different domain.
388423
389424.. _`Shared Kernel` : http://ddd.fed.wiki.org/view/shared-kernel
0 commit comments