Good bye filters, hello HTTP middleware

Filters are a great way to hook into your requests either before or after and Laravel has done a great work providing the tools we need however there was no clear convention on where to store objects (if you wanted to use objects instead of a callback) and their definition was in a filters.php file(kind of old school). In Laravel 5 filters have been replaced with HTTP Middleware which work in a similar way but more organised.

All middleware objects are stored in:

app/Http/Middleware/*

To create a new middleware you can use Laravel’s generators:

php artisan make:middleware OldMiddleware

The next step is to register the filter either globally (applies to all requests) or assign a key and use it per route, you can do both in:

app/Http/Kernel.php

To assign it to a specific route use “middleware” property:

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

To assign multiple middleware objects to a route define them in an array:

Route::get('/', ['middleware' => ['MyMiddleware', 'MySecondMiddleware'], function () {
    //
}]); 

When multiple middleware objects are registered for 1 route they are executed in order in which they were defined, in the example above “MyMiddleware” will be executed first.

To pass custom parameters to the middleware first define it in handle() method:


<?php namespace App\Http\Middleware;

use Closure;

class RoleMiddleware
{
  /**
    * Run the request filter.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Closure  $next
    * @param  string  $param
    * @return mixed
    */
    public function handle($request, Closure $next, $param)
    {
       //
       return $next($request);
     }
  }

To pass params use “:” notation and “,” to separate multiple params:

Route::get('/', ['middleware' => 'MyMiddleware:param1,param2', function () {
    //
}]); 

Another important feature is “Terminable Middleware” which will be executed after the response has been sent, do not confuse with after filters from Laravel 4 which were executed after the request but before sending the response. To define it, add “terminate()” method to a middleware object:


<?php namespace App\Http\Middleware;

use Closure;

class RoleMiddleware
{
  /**
    * Run the request filter.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Closure  $next
    * @param  string  $param
    * @return mixed
    */
    public function handle($request, Closure $next, $param)
    {
       //
       return $next($request);
     }

    public function terminate($request, $response)
    {
        // Log something?
    }
  }