Skip to content

Commit b5dd0e9

Browse files
committed
feature #6840 Added a new article about applications with multiple kernels (javiereguiluz)
This PR was merged into the 2.7 branch. Discussion ---------- Added a new article about applications with multiple kernels This fixes #997 (opened in January 2012 !!!). --- 1) I don't know which is the best location for this article (probably not `request/`) 2) When merging up, in the 2.8 branch the following must be added: At the end of `Step 2)`, add this: ``` rst In order to make this class available in the front controller, don't forget to add it to the ``classmap`` configuration of the ``composer.json`` file: .. code-block:: json { "autoload": { "psr-4": { "": "src/" }, "classmap": ["app/AppKernel.php", "app/ApiKernel.php"] }, ... } ``` At the end of the article, add this: ``` rst .. tip: Symfony 2.8 introduced a `new micro kernel`_ PHP trait that simplifies the creation of kernels. You can even define them in a single PHP file. .. _`new micro kernel`: http://symfony.com/blog/new-in-symfony-2-8-symfony-as-a-microframework ``` Commits ------- bc3618d Made a bunch of fixes recommended by Ryan 2613810 Added a note about rendering templates from different kernels e403fd8 Added a new section about running commands under a different kernel af4ff18 Added a new use case related to micro-services 2c5aeb1 Removed a use case 097a73d Reworded the use cases section 5c8ed87 Fixed typo d45e1f4 Fixed an example code a23d82d Fixed another syntax issue 21329ec Fixed some syntax issues 7cb2aa1 Added a new article about applications with multiple kernels
2 parents 2ad7092 + bc3618d commit b5dd0e9

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed

request/multiple_kernels.rst

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
.. index::
2+
single: kernel, performance
3+
4+
How To Create Symfony Applications with Multiple Kernels
5+
========================================================
6+
7+
In most Symfony applications, incoming requests are processed by the
8+
``web/app.php`` front controller, which instantiates the ``app/AppKernel.php``
9+
class to create the application kernel that loads the bundles and handles the
10+
request to generate the response.
11+
12+
This single kernel approach is a convenient default provided by the Symfony
13+
Standard edition, but Symfony applications can define any number of kernels.
14+
Whereas :doc:`environments </configuration/environments>` execute the same
15+
application with different configurations, kernels can execute different parts
16+
of the same application.
17+
18+
These are some of the common use cases for creating multiple kernels:
19+
20+
* An application that defines an API could define two kernels for performance
21+
reasons. The first kernel would serve the regular application and the second
22+
one would only respond to the API requests, loading less bundles and enabling
23+
less features;
24+
* A highly sensitive application could define two kernels. The first one would
25+
only load the routes that match the parts of the application exposed publicly.
26+
The second kernel would load the rest of the application and its access would
27+
be protected by the web server;
28+
* A micro-services oriented application could define several kernels to
29+
enable/disable services selectively turning a traditional monolith application
30+
into several micro-applications.
31+
32+
Adding a new Kernel to the Application
33+
--------------------------------------
34+
35+
Creating a new kernel in a Symfony application is a three-step process:
36+
37+
1. Create a new front controller to load the new kernel;
38+
2. Create the new kernel class;
39+
3. Define the configuration loaded by the new kernel.
40+
41+
The following example shows how to create a new kernel for the API of a given
42+
Symfony application.
43+
44+
Step 1) Create a new Front Controller
45+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46+
47+
Instead of creating the new front controller from scratch, it's easier to
48+
duplicate the existing ones. For example, create ``web/api_dev.php`` from
49+
``web/app_dev.php`` and ``web/api.php`` from ``web/app.php``.
50+
51+
Then, update the code of the new front controllers to instantiate the new kernel
52+
class instead of the usual ``AppKernel`` class::
53+
54+
// web/api.php
55+
// ...
56+
$kernel = new ApiKernel('prod', false);
57+
// ...
58+
59+
// web/api_dev.php
60+
// ...
61+
$kernel = new ApiKernel('dev', true);
62+
// ...
63+
64+
Step 2) Create the new Kernel Class
65+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66+
67+
Now you need to define the ``ApiKernel`` class used by the new front controller.
68+
The easiest way to do this is by duplicating the existing ``app/AppKernel.php``
69+
file and make the needed changes.
70+
71+
In this example, the ``ApiKernel`` will load less bundles than AppKernel. Be
72+
sure to also change the location of the cache, logs and configuration files so
73+
they don't collide with the files from ``AppKernel``::
74+
75+
// app/ApiKernel.php
76+
use Symfony\Component\HttpKernel\Kernel;
77+
use Symfony\Component\Config\Loader\LoaderInterface;
78+
79+
class ApiKernel extends Kernel
80+
{
81+
public function registerBundles()
82+
{
83+
// load only the bundles strictly needed for the API...
84+
}
85+
86+
public function getCacheDir()
87+
{
88+
return dirname(__DIR__).'/var/cache/api/'.$this->getEnvironment();
89+
}
90+
91+
public function getLogDir()
92+
{
93+
return dirname(__DIR__).'/var/logs/api';
94+
}
95+
96+
public function registerContainerConfiguration(LoaderInterface $loader)
97+
{
98+
$loader->load($this->getRootDir().'/config/api/config_'.$this->getEnvironment().'.yml');
99+
}
100+
}
101+
102+
Step 3) Define the Kernel Configuration
103+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
104+
105+
Finally, define the configuration files that the new ``ApiKernel`` will load.
106+
According to the above code, this config will live in the ``app/config/api/``
107+
directory.
108+
109+
The new configuration can be created from scratch when you load just a few
110+
bundles, because it will be very simple. Otherwise, duplicate the existing
111+
config files or better, import them and override the needed options:
112+
113+
.. code-block:: yaml
114+
115+
# app/config/api/config_dev.yml
116+
imports:
117+
- { resource: ../config_dev.yml }
118+
119+
# override option values ...
120+
121+
Executing Commands with a Different Kernel
122+
------------------------------------------
123+
124+
The ``bin/console`` script used to run Symfony commands always uses the default
125+
``AppKernel`` class to build the application and load the commands. If you need
126+
to execute console commands using the new kernel, duplicate the ``bin/console``
127+
script and rename it (e.g. ``bin/api``).
128+
129+
Then, replace the ``AppKernel`` instantiation by your own kernel instantiation
130+
(e.g. ``ApiKernel``) and now you can execute commands using the new kernel
131+
(e.g. ``php bin/api cache:clear``) Now you can use execute commands using the
132+
new kernel.
133+
134+
.. note::
135+
136+
The commands available for each console script (e.g. ``bin/console`` and
137+
``bin/api``) can differ because they depend on the bundles enabled for each
138+
kernel, which could be different.
139+
140+
Rendering Templates Defined in a Different Kernel
141+
-------------------------------------------------
142+
143+
If you follow the Symfony Best Practices, the templates of the default kernel
144+
will be stored in ``app/Resources/views/``. Trying to render those templates in
145+
a different kernel will result in a *There are no registered paths for
146+
namespace "__main__"* error.
147+
148+
In order to solve this issue, add the following configuration to your kernel:
149+
150+
.. code-block:: yaml
151+
152+
# api/config/config.yml
153+
twig:
154+
paths:
155+
# allows to use app/Resources/views/ templates in the ApiKernel
156+
"%kernel.root_dir%/../app/Resources/views": ~
157+
158+
Adding more Kernels to the Application
159+
--------------------------------------
160+
161+
If your application is very complex and you create several kernels, it's better
162+
to store them in their own directories instead of messing with lots of files in
163+
the default ``app/`` directory:
164+
165+
.. code-block:: text
166+
167+
project/
168+
├─ app/
169+
│ ├─ ...
170+
│ ├─ config/
171+
│ └─ AppKernel.php
172+
├─ api/
173+
│ ├─ ...
174+
│ ├─ config/
175+
│ └─ ApiKernel.php
176+
├─ ...
177+
└─ web/
178+
├─ ...
179+
├─ app.php
180+
├─ app_dev.php
181+
├─ api.php
182+
└─ api_dev.php

0 commit comments

Comments
 (0)