0

Explain the Laravel request lifecycle in detail

Advanced5 min read·eng-10-001
interview

Concept

The Laravel request lifecycle — what happens from the moment a web server hands off an HTTP request to when a response is sent back.

Full lifecycle:

  1. Web server (Nginx/Apache) receives the HTTP request and passes it to PHP-FPM via FastCGI.

  2. public/index.php: The single entry point for all web requests. Loads the Composer autoloader and creates the Application instance.

  3. bootstrap/app.php: Configures the Application container — binds the HTTP Kernel, Console Kernel, and Exception Handler.

  4. HTTP Kernel bootstrap: $kernel->handle($request) calls the kernel's bootstrap methods: load environment, load configuration, set exception handler, load service providers, boot providers.

  5. Service Providers (the most important phase): register() is called on all providers first (they can bind things into the container without depending on other bindings). Then boot() is called on all providers (now they can use any binding). This includes RouteServiceProvider which loads routes.

  6. Middleware pipeline: The request is passed through the global middleware stack (CORS, TrustProxies, ValidatePostSize, etc.).

  7. Route matching: The router matches the request path and method against registered routes.

  8. Route middleware: The matched route's middleware stack runs (auth, throttle, etc.).

  9. Controller / Closure: The route action executes. Dependencies are resolved from the container.

  10. Response sent: The response travels back through the middleware stack (terminable middleware runs), and is sent to the web server, which sends it to the client.

Code Example

php
<?php
// public/index.php — the actual entry point
define('LARAVEL_START', microtime(true));

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

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

$kernel = $app->make(\Illuminate\Contracts\Http\Kernel::class);  // 3. HTTP Kernel

$response = $kernel->handle(                // 4. Handle the request
    $request = \Illuminate\Http\Request::capture()
);

$response->send();  // 5. Send the response

$kernel->terminate($request, $response);  // 6. Run terminable middleware (e.g., DB disconnect, session save)
php
// bootstrap/app.php — Application creation and kernel binding
$app = new \Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

$app->singleton(
    \Illuminate\Contracts\Http\Kernel::class,
    \App\Http\Kernel::class  // YOUR kernel — extends Illuminate's
);

$app->singleton(
    \Illuminate\Contracts\Debug\ExceptionHandler::class,
    \App\Exceptions\Handler::class
);

return $app;
php
// App\Http\Kernel — where YOU define middleware
class Kernel extends HttpKernel
{
    // Global middleware — runs on EVERY request
    protected $middleware = [
        \App\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
        \App\Http\Middleware\ValidatePostSize::class,
    ];

    // Middleware groups — applied to route groups
    protected $middlewareGroups = [
        'web' => [
            \Illuminate\Cookie\Middleware\EncryptCookies::class,
            \Illuminate\Session\Middleware\StartSession::class,
        ],
        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
        ],
    ];

    // Named middleware aliases
    protected $middlewareAliases = [
        'auth'     => \App\Http\Middleware\Authenticate::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    ];
}

Interview Q&A

Q: When do Service Providers boot? A: All providers register() first (binding phase), then all providers boot() (can now use other bindings). The RouteServiceProvider::boot() loads routes.

Q: Can you add middleware after the route matches? A: Yes — route middleware runs after global middleware. You can attach route middleware in routes or controllers.