Symfony Microframework

Introduction

Before diving into microframeworks, it's important to understand that a framework is a pre-built software structure that provides a set of tools and libraries to facilitate the development of software applications. It typically includes a defined set of rules, conventions, and best practices that help developers create high-quality, scalable applications efficiently.

Frameworks can be broadly categorized into two types: full-stack frameworks and microframeworks.

Full-stack frameworks provide a comprehensive set of tools and features for building complex, multi-layered applications, whereas microframeworks offer only the bare essentials necessary to build lightweight, single-purpose applications.

Microframeworks are lightweight, fast, and easy to use, making them ideal for small-scale projects or prototypes. However, they may not be suitable for complex applications or projects that require extensive functionality and flexibility.

Symfony MicroKernel

Symfony MicroKernel is a lightweight version of the full-stack Symfony framework, which is designed to support the development of microservices and small-scale applications. It provides developers with a basic set of components and tools, allowing them to create a custom framework tailored to their specific needs. 

The MicroKernel approach is based on the idea of "selective dependency injection," which means that only the required components are loaded, reducing overhead and increasing performance and can be used to create a Symfony microframework application.

Requirements:

- PHP

- Composer

Installation

First, we need to install the Symfony framework bundle and the Symfony runtime library using Composer. Here's the command to run in your terminal:

composer require symfony/framework-bundle symfony/runtime

FrameworkBundle is a bundle of Symfony components that provides a foundation for web applications built with Symfony, while symfony/runtime is a library that provides a streamlined, standalone runtime environment for Symfony applications built using the MicroKernelTrait.

The Symfony/runtime provides an autoload. that will be the entrypoint of our application.

Implementation

Let's create an index.php file in the public directory. In this file, we first require the autoload file from the runtime as we said earlier: 

<?php require_once __DIR__.'/../vendor/autoload_runtime.php';

The above autoload expects the index.php to return a function, inside the function we will have access to the $context an array parameter that will include global and environement variables.

the function should returns an Symfony\Component\HttpKernel\Kernel instance.

use Symfony\Component\HttpKernel\Kernel; return static function( array $context ) { $env = $context[ 'APP_ENV' ]; $debug = $context[ 'APP_DEBUG' ]; return new class( $env, $debug) extends Kernel {}

The Kernel expects that our class to define a:

registerBundles: is responsible for registering all the bundles that will be used in our Application. In Symfony a bundle is a modular unit of code that encapsulates related functionality, making it easy to add or remove specific features. bundles are typically registered in the config/bundles.php file, but in our case we will register the bundles inline.

registerContainerConfiguration: used to register configuration files that define services/bundles for the service container. These configuration files are typically written in YAML or XML formats and are located in the config/ directory.

we can use the MicroKernelTrait as it provides us with both methods, and we overide registerBundles to register the symfony FrameworkBundle:

return new class( $env, $debug) extends Kernel { use MicroKernelTrait; public function registerBundles(): iterable { yield new FrameworkBundle(); } }

The FrameWorkBundle only require a secret. this secret is used for security resons like generating CSRF tokens. we need to configure it using the configureContainer:

public function configureContainer( ContainerConfigurator $configurator ): void { $configurator->extension( 'framework', [ 'secret' => '123456789' ] ); }

Routes and Controllers

At this stage we have a working Symfony application. we need to start creating routes and controllers, in our case we will define a dynamic route that require a number in the path:

public function configureRoutes( RoutingConfigurator $configurator ): void { $configurator->add( 'app_home', '/{number}' )->controller( [ $this, 'homeAction' ] ); } public function homeAction( int $number, Request $request ): Response { return new JsonResponse( [ 'success' => true, 'providedNumber' => $number ] ); }

And that's it, now run the symfony server, and browse yourlocalhost/1234

php -S localhost:8000 -t public/

Next, open your browser and navigate to the "localhost:8000/1234" URL. You should see the message:

{ "success": true, "providedNumber": 1234 }