webmaster-lawnstarter's avatar

How to use Middleware as Filters?

Since the Filters folder has disappeared and the Middleware Folder showed up in the Laravel 5.0 dev branch, I was wondering how one would implement the same "before" filter functionality with the new (is middleware truly new?) approach.

0 likes
14 replies
rspahni's avatar

Yes it works. My findings so far:

1) Turn filters into middleware according to these templates... https://github.com/laravel/laravel/tree/develop/app/Http/Middleware; every filter (of which I used to have several in one class as methods called via @ from FilterServiceProvider) will become a middleware class of its own that implements the Illuminate\Contracts\Routing\Middleware contract = interface and thus features one handle method where you put your logic; for the class you can choose whatever name and namespace you please (e.g. "LocalesFilter" if you want to stick to the "filter" term, App\Http\Filters namespace instead of App\Http\Middleware possible likewise if you're feeling retro).

2) Register the new middlewares in the $middleware property in AppServiceProvider whereby you give them an alias that points to the class path/namespace ('localesFilter' => 'App\Http\Middleware\LocalesFilter'); that $middleware property is referred to as "route middleware" by Taylor in the docblock, which seems to be mostly synonymous with before filter.

3) Refer to your new middlewares f.k.a. filters in routes.php [unless you're using annotations, I don't] as ['middleware' => ['localesFilter', 'your_ex-filter2', ...] where you used to have ['before' => ['localesFilter', 'your_filter2', ...]. Here you have to use the "middleware" key as it points to the respective property in your AppServiceProvider, which cannot be renamed as it appears to be hard-coded in the base Illuminate\Foundation\Support\Providers\AppServiceProvider that yours extends.

This should do it. One thing I've noticed so far: My filters up until here did not necessarily return anything as per some condition (e.g., turn filter on/off via custom config file). PhpStorm referred to those constructs as "code smell" or "inconsistent return point"... :) In any case, once filters become middleware, you need to make them return a response no matter what or you'll land at an empty page.

1 like
rspahni's avatar

On my last point: return $next($request) is what you seem to have to return from a "route middleware" f.k.a. before filter if no other condition applies:

 /**
  * @param \Illuminate\Http\Request $request
  * @param \Closure $next
  */
 public function handle($request, Closure $next)
 {
  if (...) { 
   // do conditional stuff
  } else {
   return $next($request);
  }
 }
1 like
rspahni's avatar

Nope - as I avoid annotations, I disaggregated the stuff that used to be 'except' or 'only' in my controller constructors and put it into every single route in routes.php. This file looks crap now, honestly.

bbloom's avatar

@rspahni Fabulous exposition, thank you! When this feature settles down, I will be in desperate need of Laracast screencasts about it.

webmaster-lawnstarter's avatar

@tommymarshall Thanks! that is a really detailed description. I had read that site before and never thought to check there for filters. Now I just gotta figure out how to make them appear in the [php artisan route:list] command to check all my routes. I have been writing test cases but it would be nice to have the visual information available.

FireCoding's avatar

I would love to see a laracast lesson on "middleware" to cover the concepts as described in the link from tommymarshall

webmaster-lawnstarter's avatar

Seems that by running a [composer update] today, i got the updated version of [php artisan route:list] and middleware is showing in the console overview.

JeffreyWay's avatar

Yes - we'll definitely be covering middleware soon.

2 likes
jasonlewis's avatar

Middlewares are cool, but remember these two things when you're about to make something into a middleware.

  1. Filters can receive parameters at run-time, something a middleware is unable to do.
  2. A "before" middleware will not have access to the current route as the router has not yet been dispatched in the application lifecycle.
1 like

Please or to participate in this conversation.