Understanding the Request Lifecycle, Service Container, and Facades

ayako_yk

Ayako yk

Posted on September 9, 2023

Understanding the Request Lifecycle, Service Container, and Facades

This topic may seem a bit advanced to me, but I believe it's crucial to grasp how a Laravel application works. This article provides an overview of the official documentation, emphasizing the simplification of essential concepts for better understanding.

Glossary
Bootstrap: Refers to the process of starting up a computer or software application. It often implies the initial setup or starting point for a system or program to become functional.
Kernel: A vital OS component that acts as a bridge between hardware and software, allowing multiple applications to share and access computer resources like CPU, memory, storage, and networking.

Request Lifecycle

The application instance is created, the service providers are registered, and the request is handed to the bootstraped application.
Laravel

The entry point of a Laravel application is the public/index.php file.

<?php

use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;

define('LARAVEL_START', microtime(true));

/*
|--------------------------------------------------------------------------
| Check If The Application Is Under Maintenance
|--------------------------------------------------------------------------
|
| If the application is in maintenance / demo mode via the "down" command
| we will load this file so that any pre-rendered content can be shown
| instead of starting the framework, which could cause an exception.
|
*/

if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
    require $maintenance;
}

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| this application. We just need to utilize it! We'll simply require it
| into the script here so we don't need to manually load our classes.
|
*/

require __DIR__.'/../vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request using
| the application's HTTP kernel. Then, we will send the response back
| to this client's browser, allowing them to enjoy our application.
|
*/

$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Kernel::class);

$response = $kernel->handle(
    $request = Request::capture()
)->send();

$kernel->terminate($request, $response);

Enter fullscreen mode Exit fullscreen mode

First, the public/index.php file loads Composer, which provides a convenient, automatically generated class loader for the application, and retrieves an instance of the Laravel application from bootstrap/app.php.

Next, the incoming request is sent to either the HTTP kernel or the console kernel. These kernels serve as central locations through which all requests flow. The HTTP kernel, in particular, executes bootstrappers that handle tasks necessary before handling requests and defines all the middleware.

HTTP/Kernel.php

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array<int, class-string|string>
     */
    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array<string, array<int, class-string|string>>
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    /**
     * The application's middleware aliases.
     *
     * Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
     *
     * @var array<string, class-string|string>
     */
    protected $middlewareAliases = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
        'signed' => \App\Http\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];
}
Enter fullscreen mode Exit fullscreen mode

Service providers are loaded. Service providers play a crucial role as they bootstrap various components of the framework.

The App\Providers\RouteServiceProvider is vital for routing in Laravel. It loads route files, defines how requests are handled and runs middleware. Middleware checks incoming requests (e.g., user authentication) and directs them accordingly. If a request passes middleware, it triggers the associated route or controller method, and the response goes through more middleware before reaching the client.

<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * The path to your application's "home" route.
     *
     * Typically, users are redirected here after authentication.
     *
     * @var string
     */
    public const HOME = '/home';

    /**
     * Define your route model bindings, pattern filters, and other route configuration.
     */
    public function boot(): void
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
        });

        $this->routes(function () {
            Route::middleware('api')
                ->prefix('api')
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->group(base_path('routes/web.php'));
        });
    }
}

Enter fullscreen mode Exit fullscreen mode

Service Container
The Laravel service container is a class instance that automatically manages class dependencies and performs dependency injection without the need for manual binding.

Service Provider
To add our own service providers in Laravel, we typically include them in the config/app.php file within the provider's array.

Facades
Facades are built-in classes in Laravel that provide a convenient and expressive way to access services from the service container. To use a facade, we typically import it using the use statement at the top of our class or component.

routes/web.php

use Illuminate\Support\Facades\Route;

Route::get('/', fn () => view('landing'))->name('landing');
Enter fullscreen mode Exit fullscreen mode

There's more to delve into to understand the inner workings of a Laravel application. However, as the documentation states, 'When you understand how your development tools function, you feel more comfortable and confident using them.' With this knowledge, I'm well-equipped to move forward and enjoy creating applications.

💖 💪 🙅 🚩
ayako_yk
Ayako yk

Posted on September 9, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related