Middleware groups in Laravel 5.2

Posted on December 22, 2015

Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.

When you are creating a site of any significant size in Laravel, your routes file will often get pretty large. One of the first things I do in a new site is group my routes by logically distinct sections like "admin", "auth", "public". Usually each of these groups get their own set of middleware—admin, for example, gets auth. Maybe the API group gets a different auth middleware, and it might get an API-specific rate limiter or something else.

Laravel 5.2 has introduced something called middleware groups, which are essentially a shortcut to applying a larger group of middleware, using a single key.

Note: Even if you don't want to use the middleware "shortcuts" aspect of middleware groups, you should read on, because this is a big change to Laravel's global middleware stack.

So remember my admin example above? We can now create an "admin" middleware group. Let's learn how.

Defining middleware groups

You can define middleware groups in app\Http\Kernel.php. There's a new property named $middlewareGroups that's an array; each key is a name and each value is the corresponding middleware.

Out of the box, it comes with web and api:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
    ],

    'api' => [
        'throttle:60,1',
    ],
];

As you can see, the keys can reference either a class or a route-specific middleware shortcut like throttle or auth. Let's make an admin group:

protected $middlewareGroups = [
    'web' => [...],
    'api' => [...],
    'admin' => [
        'web',
        'auth',
    ]
];

We've defined that the admin is a group that uses web (another group) and auth (a named route middleware). That's it!

Changes from 5.1

You might notice that the middleware in web are those that used to be applied to every route in Laravel 5.1 and before. That's a pretty big shift in thinking, so please take note of that: anything that's not given a web middleware will not have cookies or session or CSRF functional.

That also means we have a lot more flexibility, though: it frees us up to have more stateless API layers that aren't giving us the convenience of cookies and sessions. We can get rid of most of the universal middleware—if you take a look, the only universal middleware in 5.2 is the "check for maintenance mode" middleware.

Note as well that any APIs that rely on cookies or sessions (or CSRF) will not work if they're stuck under this api group, so if you have stateful APIs, you'll need to make some tweaks to this default api group.

Using middleware groups

OK, so we know how to define a middleware group. How do we use it?

It'll be clear when you look at the default routes.php in 5.2:

Route::get('/', function () {
    return view('welcome');
});

Route::group(['middleware' => ['web']], function () {
    //
});

As you can see, you use it just like any route middleware like auth: just put the key either as the direct value of middleware, or in an array that's the value of middleware. So, here's our admin middleware group in use:

Route::group(['middleware' => 'admin'], function () {
    Route::get('dashboard', function () {
        return view('dashboard');
    });
});

That's it! Enjoy!

Note: Later in Laravel 5.2, all routes in routes.php are now wrapped with the web middleware group by default. I'll try to write that up more later, but take a look at the RouteServiceProvider to see how it's all working.


Comments? I'm @stauffermatt on Twitter


Tags: laravel  •  laravel 5.2  •  middleware


(This is part of a series of posts on New Features in Laravel 5.2. )

  1. Dec 17, 2015 | laravel, laravel 5.2
    It's time to start writing about the new features in Laravel 5.2! You'll notice that many of these features are quicker and e...
  2. Dec 18, 2015 | laravel, laravel 5.2
    If you've never used it, Laravel's route model binding has been around for a while, but Laravel 5.2 is about to make it even ...
  3. Dec 19, 2015 | laravel, laravel 5.2, API
    More and more of my work in Laravel lately has been creating APIs. I have a manual rate limiter class I've been using, but I'...
  4. Dec 22, 2015 | laravel, laravel 5.2, middleware
    When you are creating a site of any significant size in Laravel, your routes file will often get pretty large. One of the fir...
  5. Jan 8, 2016 | laravel, laravel 5.2
    If you're like me, many of the applications you build in Laravel have a similar Saas-type framework: user signup, user login,...
  6. Jan 22, 2016 | laravel, laravel 5.2, authentication
    Let's get back to Laravel 5.2 features, shall we? 5.2 introduced a significant boost to the power of the entire authenticatio...

Subscribe

For quick links to fresh content, and more thoughts that don't make it to the blog