One of the key features of Laravel is the ability to create and register middleware - special functions that allow you to process and filter HTTP requests coming into your application.
This can be useful for performing various tasks such as user authentication, authorizing access to certain functions, checking and setting headers, etc.
Starting with Laravel 11, the developers have made incompatible changes, with past versions, in the handling of middleware. While in previous versions you could add middleware in the app/Http/Kernel.php
file, since Laravel 11, you need to change middleware in the bootstrap/app.php
file.
If you look deeper into the Http Kernel, all the logic from previous versions has moved to the Illuminate\Foundation\Configuration\Middleware
object in the defaultAliases(), getMiddlewareGroups(), getGlobalMiddleware() methods. Inside is the same candy but in a different package.
In this version, the standard view of the app.php
file looks like this:
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
The withMiddleware method ensures that middleware is launched on every HTTP request, it can be called a global stack. This is the best place to define middleware for all application routes.
In previous versions, the property \App\Http\Kernel@$middleware = []
was used for this purpose.
The Middleware object contains two methods for append to add to the end of the list and prepend to add middleware to the beginning respectively.
function (Middleware $middleware) {
// string
$middleware->append(\App\Http\Middleware\AssignRequestId::class);
// array
$middleware->prepend([
\App\Http\Middleware\EncryptCookies::class,
]);
}
The use method is used to override the standard middleware list.
$middleware = $this->global ?: array_values(array_filter([
Illuminate\Foundation\Http\Middleware\InvokeDeferredCallbacks::class,
$this->trustHosts ? \Illuminate\Http\Middleware\TrustHosts::class : null,
\Illuminate_Http_Middleware_TrustProxies::class,
\Illuminate Http/Middleware/HandleCors::class,
\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate/Http\Middleware/ValidatePostSize::class,
\Illuminate/Foundation\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
]));
You can also use the remove method call to remove the default middleware
$middleware->remove(\Illuminate\Http\Middleware\ValidatePostSize::class);
Registering middleware in Laravel 11: Basic steps
Registering middleware is an important aspect of Laravel development that allows you to understand your application's execution cycle and control the flow of requests and responses from the server.
Understanding how to properly register and use middleware can eliminate "magic bugs" and make your application more functional and usable for the whole team.
The middleware registration process looks like this:
- Create a new middleware file in the
app/Http/Middleware
folder, either manually or using the console command. - Write the code for your middleware in the handle method.
- Register the middleware in
config/app.php
if you want it to trigger on every call. - Or use middleware in your controller or route.
Here is an example of middleware registration for clarity.
->withMiddleware(function (Middleware $middleware) {
$middleware->append([
\App\Http\Middleware\EnsureTokenIsValid::class,
]);
$middleware->alias(['ensureTokenIsValid' =>
\App\Http\Middleware\EnsureTokenIsValid::class,]);
});
Registering middleware with Invoke classes
When your application has a large number of instructions the app.php
file becomes hard to read and it makes sense to put the implementation in a separate class.
Since withMiddleware
takes callable type as input we can pass an object that will be executed as a function. To execute an object as a function we need to implement only one method __invoke()
.
class CallableMiddleware
{
protected $appends = [];
public function __invoke(Middleware $middleware)
{
$middleware->appends($this->appends);
}
}
// app.php
....
->withMiddleware(new CallableMiddleware());
Register a route middleware
Omit the registration of the globaware middleware, in the app.php
file, if you want to assign it to specific routes:
Route::get('/dashboard', function () {
// ...
})->middleware(EnsureTokenIsValid::class);
After defining new middleware or changing old middleware, it is recommended to clear the cached files of the application to ensure that Laravel works correctly. You can run the following Artisan command:
php artisan optimize:clear
For a deeper understanding of the registration process and the use of methods, it is recommended to refer to the official Laravel documentation or review the HTTP core code yourself.