What are Sorting Middleware in Laravel and where do we use it

Ashutosh Kukreti

Sorting middleware in Laravel is used to specify the order in which middleware should be executed for a particular request. This can be useful when you have multiple middleware that need to be executed in a specific order.

To sort middleware, you can use the middlewarePriority property in the App\Http\Kernel class. This property is an array that maps middleware class names to their priority levels. The priority levels should be integers, where lower numbers indicate higher priority.

Here is an example of how to use middlewarePriority to sort middleware:

protected $middlewarePriority = [
    \App\Http\Middleware\FirstMiddleware::class,
    \App\Http\Middleware\SecondMiddleware::class,
    \App\Http\Middleware\ThirdMiddleware::class,
];

In this example, FirstMiddleware will be executed first, followed by SecondMiddleware, and then ThirdMiddleware. If two middleware have the same priority level, Laravel will execute them in the order in which they are defined in the $middleware array.

You can also define middleware priority on a per-route basis by using the middlewarePriority method in the route definition:

Route::get('/my-route', 'MyController@myAction')
    ->middleware(['third', 'second', 'first'])
    ->middlewarePriority([
        \App\Http\Middleware\FirstMiddleware::class,
        \App\Http\Middleware\SecondMiddleware::class,
        \App\Http\Middleware\ThirdMiddleware::class,
    ]);

In this example, the middleware for the /my-route route will be executed in the order of third, second, and first, but the middleware priority is set to execute FirstMiddleware first, followed by SecondMiddleware, and then ThirdMiddleware.

Sorting middleware is useful in cases where the order in which middleware is executed is important, such as when you need to set up dependencies between middleware, or when you need to ensure that certain middleware is executed before others.

Lets understand with the help of practical example

Suppose you have an application that requires authentication and authorization for certain routes. You might have a middleware for each of these tasks:

namespace App\Http\Middleware;

use Closure;

class Authenticate
{
    public function handle($request, Closure $next)
    {
        // Authenticate the user...

        return $next($request);
    }
}

namespace App\Http\Middleware;

use Closure;

class Authorize
{
    public function handle($request, Closure $next)
    {
        // Authorize the user...

        return $next($request);
    }
}

You could then apply these middleware to your routes like so:

Route::get('/dashboard', 'DashboardController@index')
    ->middleware(['auth', 'authorize']);

However, the order in which these middleware are executed matters: you need to authenticate the user before you can authorize them. To ensure that this happens, you can use sorting middleware:

namespace App\Http\Middleware;

use Closure;

class AuthenticateAndAuthorize
{
    public function handle($request, Closure $next)
    {
        return app(Authorize::class)->handle(
            $request,
            function ($request) use ($next) {
                return app(Authenticate::class)->handle($request, $next);
            }
        );
    }
}

In this example, AuthenticateAndAuthorize is a sorting middleware that wraps the Authenticate and Authorize middleware. When a request comes in, AuthenticateAndAuthorize calls Authorize first, passing in a closure that calls Authenticate once authorization is complete.

You can then apply AuthenticateAndAuthorize to your route:

Route::get('/dashboard', 'DashboardController@index')
    ->middleware(['authenticate-and-authorize']);

This ensures that the user is authenticated before they are authorized to access the dashboard.

Thats all for this tutorial. We'll learn about controllers

Laravel