Skip to content

[FrameworkBundle] Simplified the MicroKernelTrait setup #19977

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 21, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 60 additions & 47 deletions configuration/micro_kernel_trait.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ via Composer:

.. code-block:: terminal

$ composer require symfony/config symfony/http-kernel \
symfony/http-foundation symfony/routing \
symfony/dependency-injection symfony/framework-bundle
$ composer symfony/framework-bundle symfony/runtime

Next, create an ``index.php`` file that defines the kernel class and runs it:

Expand All @@ -34,19 +32,12 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Attribute\Route;

require __DIR__.'/vendor/autoload.php';
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to update the composer require section with symfony/runtime libs ;)

Copy link
Member

@yceruto yceruto Jun 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that section only symfony/framework-bundle is required actually, the other ones are transitive dependencies anyway, not sure we wanted to make them explicit though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I think that, generally speaking, we don't list transitive dependencies in the docs, so let's remove anything that is not strictly needed. Thanks!


class Kernel extends BaseKernel
{
use MicroKernelTrait;

public function registerBundles(): array
{
return [
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
];
}

protected function configureContainer(ContainerConfigurator $container): void
{
// PHP equivalent of config/packages/framework.yaml
Expand All @@ -64,11 +55,9 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
}
}

$kernel = new Kernel('dev', true);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
return static function (array $context) {
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
}

.. code-block:: php

Expand All @@ -80,19 +69,12 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

require __DIR__.'/vendor/autoload.php';
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

class Kernel extends BaseKernel
{
use MicroKernelTrait;

public function registerBundles(): array
{
return [
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
];
}

protected function configureContainer(ContainerConfigurator $container): void
{
// PHP equivalent of config/packages/framework.yaml
Expand All @@ -114,17 +96,9 @@ Next, create an ``index.php`` file that defines the kernel class and runs it:
}
}

$kernel = new Kernel('dev', true);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

.. note::

In addition to the ``index.php`` file, you'll need to create a directory called
``config/`` in your project (even if it's empty because you define the configuration
options inside the ``configureContainer()`` method).
return static function (array $context) {
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
}

That's it! To test it, start the :doc:`Symfony Local Web Server
</setup/symfony_server>`:
Expand All @@ -135,14 +109,50 @@ That's it! To test it, start the :doc:`Symfony Local Web Server

Then see the JSON response in your browser: http://localhost:8000/random/10

.. tip::

If your kernel only defines a single controller, you can use an invokable method::

class Kernel extends BaseKernel
{
use MicroKernelTrait;

// ...

#[Route('/random/{limit}', name: 'random_number')]
public function __invoke(int $limit): JsonResponse
{
// ...
}
}

The Methods of a "Micro" Kernel
-------------------------------

When you use the ``MicroKernelTrait``, your kernel needs to have exactly three methods
that define your bundles, your services and your routes:

**registerBundles()**
This is the same ``registerBundles()`` that you see in a normal kernel.
This is the same ``registerBundles()`` that you see in a normal kernel. By
default, the micro kernel only registers the ``FrameworkBundle``. If you need
to register more bundles, override this method::

use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
// ...

class Kernel extends BaseKernel
{
use MicroKernelTrait;

// ...

public function registerBundles(): array
{
yield new FrameworkBundle();
yield new TwigBundle();
}
}

**configureContainer(ContainerConfigurator $container)**
This method builds and configures the container. In practice, you will use
Expand All @@ -151,9 +161,13 @@ that define your bundles, your services and your routes:
services directly in PHP or load external configuration files (shown below).

**configureRoutes(RoutingConfigurator $routes)**
Your job in this method is to add routes to the application. The
``RoutingConfigurator`` has methods that make adding routes in PHP more
fun. You can also load external routing files (shown below).
In this method, you can use the ``RoutingConfigurator`` object to define routes
in your application and associate them to the controllers defined in this very
same file.

However, it's more convenient to define the controller routes using PHP attributes,
as shown above. That's why this method is commonly used only to load external
routing files (e.g. from bundles) as shown below.

Adding Interfaces to "Micro" Kernel
-----------------------------------
Expand Down Expand Up @@ -231,7 +245,10 @@ Now it looks like this::
namespace App;

use App\DependencyInjection\AppExtension;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Bundle\WebProfilerBundle\WebProfilerBundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
Expand All @@ -241,18 +258,14 @@ Now it looks like this::
{
use MicroKernelTrait;

public function registerBundles(): array
public function registerBundles(): iterable
{
$bundles = [
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new \Symfony\Bundle\TwigBundle\TwigBundle(),
];
yield FrameworkBundle();
yield TwigBundle();

if ('dev' === $this->getEnvironment()) {
$bundles[] = new \Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
yield WebProfilerBundle();
}

return $bundles;
}

protected function build(ContainerBuilder $containerBuilder): void
Expand Down
Loading