Registering Middleware

Registering Middleware in bootstrap/app.php

Since Laravel 11 2,157 a new application has no app/Http/Kernel.php. All registration happens in the withMiddleware closure of bootstrap/app.php (bootstrap/app.php), which receives an Illuminate\Foundation\Configuration\Middleware builder. This is the bookshop's closure; the withRouting call above it gained api: __DIR__.'/../routes/api.php', which loads that file under the api prefix and middleware group, and the file's use block imports the four classes named here.

The withMiddleware closure in bootstrap/app.phpPHP
->withMiddleware(function (Middleware $middleware): void {
    $middleware->append(AddServerTiming::class);          // global: every request
    $middleware->alias([
        'api.key' => RequireApiKey::class,
        'locale' => SetLocale::class,
    ]);
    $middleware->appendToGroup('catalog', ['api.key', 'locale:en,ms,zh']);
    $middleware->prependToPriorityList(                   // check the key before
        before: SubstituteBindings::class,                // any database lookup
        prepend: RequireApiKey::class,
    );
    $middleware->preventRequestForgery(except: ['webhooks/*']);
})

The builder's other methods follow the same pattern. The global stack takes append, prepend, remove, replace and use([...]), which replaces it outright. Groups take web() and api() with append:, prepend:, remove: and replace: arguments, or appendToGroup, prependToGroup, removeFromGroup and group('name', [...]) for any group. Built-ins are configured in place with trustProxies, trustHosts, encryptCookies, throttleApi and redirectGuestsTo. A class used on a few routes needs no registration at all: pass it to ->middleware(...) (Terminable Middleware).