Laravel: Making middleware understandable


Photo by Jida Li on Unsplash

One of the magic around Laravel middleware is how you declare them in your routes: using just a simple string. To quote an example, the request throttler is called throttle, and you can set it in one line along some parameters.

This is not magic. The middleware name is aliased in the HTTP Kernel of your application, which avoids you using the full middleware namespace.

The case of large middleware declarations

The point of middleware is how simple they’re to declare. Most of the time you’re a string away, but you may have a package that inevitability demands you to set a large set of parameters.

For example, my Captchavel package contains a middleware that, depending on the application, can require around three to four parameters.

Two ways to declare middleware: with the alias, or using the class name directly.

The latest PR I made wanted to simplify this using a small idea: what about declaring a Stringable object? Once the objects goes into the middleware method, it transforms into a string and walá. Well, that’s now possible.

We can use a fluid setter that will translate a bunch of what-does-what strings into something with lower cognitive load to understand.

The direct benefits are not in the framework, since the only middleware that requires more than one parameter is throttle, and that one is used rarely.

Rather, the huge amount of packages that must deal with middleware will benefit from this. By using a Stringable object we can:

  1. avoid using the middleware by the class name if it’s not aliased, and
  2. set parameters in any order.

While the declaration becomes larger by a few characters, the intention is clearer, which is a huge win in terms of maintainability.

Behind the scenes, any class object implementing the Stringable interface will do the heavy lifting on the __toString() method. For example, this is a simplified example of how the ReCaptcha class helper works:

There are a myriad of advantages of using objects that can be represented as strings. To summarize:

  • Lower cognitive load to understand what value does what.
  • It’s no longer obligatory to register an alias into the HTTP Kernel.
  • It’s no longer required to push a middleware class names and concatenate parameters manually.
  • You can set values in any order.
  • You can set a defaults values in the helper instead of the middleware itself.

The one caveat of declaring middlewares is the nature of the parameters. All parameters that are passed to the middleware will become strings. You will have to cast them into their appropriate type inside your middleware, like in the case of integers, decimals and lists.

Since all parameters are strings, the last member of the string foo, will transform into an empty string, not in null, so you may need to act accordingly in your middleware.

Overall, it’s a nice addition to the framework. It could have been simpler if we could have used union types for the argument, transform the string into an array, and cast to an string each member, but that would have been catastrophic as it would have broken the app for anybody below PHP 8.

I hope this little feature helps when dealing with middleware that quickly becomes a one line scrawl.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Italo Baeza Cabrera

Italo Baeza Cabrera

Graphic Designer graduate. Full Stack Web Developer. Retired Tech & Gaming Editor.