Get Laravel Route Parameters in Middleware

Access Laravel route parameters using middleware.

In the past, we've talked about simple Laravel routing and Laravel route parameters. Today we'll be talking about how to use route parameters in middleware, a task that may come up in your workflow.

What is Middleware?

A middleware simply wraps an application's request. Think of it this way, when a request is made to your application, there's code that handles the request, but if you want something to occur before or after the code that handles the request is run, you would put in a middleware.

Laravel comes with a few inbuilt middlewares for maintenance, authentication and CSRF protection, which are all found in the app/Http/Middleware directory inside a laravel project folder.

Laravel Route Parameters

Laravel routes are located in the app/Http/routes.php file. A route usually has the URL path, and a handler function callback, which is usually a function written in a certain controller.

// Inline function to handle the route
Route::get('/', function () {
    return view('welcome');
});

// Controller function to handle the route
Route::get('/profile', 'ProfileController@index');

A parameter provided in the route is usually annotated with curly braces. For instance, to pass in a name parameter to a route, it would look like this.

Route::get('/params/{name}', function ($name) {
    return $name
});

By convention, the Controller function accepts parameters based on the parameters provided.

Accessing Route Parameters

Accessing parameters in a middleware however is not that direct. First let's create a middleware called DumpMiddleware that dumps the parameters provided in the route.

php artisan make:middleware DumpMiddleware

The file app/Http/Middlware/DumpMiddleware.php is created.

Method 1: $request->route('parameter_name')

We can access route parameters in two ways. One way is by using $request->route('parameter_name')., where parameter_name refers to what we called the parameter in the route. In the handle method within the DumpMiddleware class created in the app/Http/Middleware/DumpMiddleware.php file.

public function handle($request, Closure $next)
{   
    dd($request->route('parameter_name'));
    return $next($request);
}

To see the middleware in action, let's add it to the route. Quickly create the route we showed above and add the middleware in the app/Http/routes.php file.

Route::get('/params/{name}', [
    'middleware' => 'App\Http\Middleware\DumpMiddleware',
     function () {
        return view('welcome');
}]);

We need the full namespace of the middleware, because we have not made Laravel aware of our new middleware. To do this we add it in the App\Http\Kernel.php file, as part of the $routeMiddleware class property.

protected $routeMiddleware = [
    // Middlewares commented out for brevity
    'DumpMiddleware' => \App\Http\Middleware\DumpMiddleware::class,
];

You can then update the middleware in the route to be 'middleware' => 'DumpMiddleware',.

Run php artisan serve on your terminal and open http://localhost:8000/params/scotch. You should see scotch dumped in the browser.

Method 2: $request->route()->paremeters()

The other way to access the Route parameters in the middlware involves gettting all the parameters. Imagine you had a route like this /params/{id}/{category}/{name}. All the route params are usually saved in an array, which in a middleware is accessible through $request->route()->parameters(). If we update our route to the above route,

Route::get('/params/{id}/{category}/{name}', [
    'middleware' => DumpMiddleware',
     function () {
        return view('welcome');
}]);

And update the middleware's handle method to,

public function handle($request, Closure $next)
{   
    dd($request->route()->parameters());
    return $next($request);
}

Going to http://localhost:8000/params/23/scotch/school should dump the parametes in your browser as an array, with the parameter names as the keys, and what was passed as values.

Why Access Route Parameters in Middleware?

A sample usage for accessing route parameters in middleware is when a given route performs different actions. Say for instance you have a route that returns user's profiles, /{username}. To go to Scotch's profile for instance, one would go to http://localhost:8000/scotch.

This app, however, may have some routes that do not necessarily belong to profiles. Like faq, or support, or help. In such a scenario, it is usually recommended to have these routes defined before the route that looks for a profile.

app/http/routes.php

Route::get('/faq', function() {
    return view('faq');
});
Route::get('/help', function() {
    return view('help');
});
Route::get('/support', function() {
    return view('support');
});

// Route that handles profile comes last
Route::get('/{username}', function() {
    return view('profile');
});

With middleware however, all we need to do is check if a value is in a defined array and redirect.

app/Http/routes.php

Route::get('/{username}',  [
     'middleware' => 'ProfileMiddleware',
     function () {
        return view('welcome');
}]);

Then in the profile middleware, we add this in the handle function.

<?php

namespace App\Http\Middleware;

use Closure;

// Add Response namespace
use Illuminate\Http\Response;

class ProfileMiddleware
{
    public function handle($request, Closure $next)
    {   
        $routes = ["faq", "support", "help"];
        $route = $request->route('username');

    // Redirect to custom page if it doesn't relate to a profile
        if (in_array($route, $routes)) {
            return new Response(view($route));
        }

        return $next($request);
    }
}

We simply check if the parameter is in a given array, and return a view based on that. In case we have any other keywords that are not neccesarrily profiles, all we need to do is add them to this array. Cleaner, right?

Ganga Chris

I'm a Full Stack Developer (Mostly JavaScript, PHP & Go).