Laravel: No need to extend your default application Controller

Who knew that sometimes so much boilerplate it’s not always necessary

When you start your project with this framework, you will note that all your Controllers created via php artisan make:controller extends a base application controller, located in App\Http\Controllers\Controller. This class offers a complete boilerplate to create your Controller without having to guess what to include, and from where.

If that wasn’t enough, this class also extends another class, Illuminate\Routing\Controller, which is an abstract class.

Artistic representation

And sometimes, you don’t need to even extend them. Let’s start with the bottom of this rabbit hole.

The Base Controller

Laravel comes with an abstract class called Controller, which we can consider like the “Base Controller”.

This class has some useful methods through its traits and that we can resume in the following:

  • Middleware functionality
  • Calling a method inside the Controller

The first is pretty obvious, since is common knowledge to use the $this->middleware() method inside the __construct() method to let the middlewares handle the Request before (or after) it hits the target Controller method.

The second is not so obvious. It exists for dispatching the Request through the associated Controller and Method defined in your routes. We can see that this is done by the dispatch() method in the ControllerDispatcher.

And what do you know. A quick glance on that code tell us that if the method callAction doesn’t exists, it will dynamically try to call the method name, and if the getMiddleware() method doesn’t exists, it assumes the Controller doesn’t register any middleware.

The utility of this method depends on what you want to do. For example, you can do something before effectively calling the method in your controller, but after the controller is instantiated and the middleware list executed.

The Application Controller

Next, we move up to the “Application Controller”, which is a handy class created by default to allow you access to some useful tools out-of-the-box. Let’s see what they are.

As we can see, there are three traits in this Controller: AuthorizesRequests, DispatchesJobs and ValidatesRequests.

Authorizing Requests

This trait is in charge of adding methods to authorize the Request before it further processing. This is documented as a Authorization Controller Helper.

If you’re totally not using the authorization helpers in your Controller, like when using auto-discovering of Policies or Gates, use seems like a safe bet to not use this trait.

Dispatching Jobs

This trait is very lean: it’s only has two methods that saves you resolving the Dispatcher service from the Service Container.

This allows you to dispatch a Job using this style:

public function dispatchMe(Request $request)
{
$this->dispatch(new ProcessPodcast);
$this->dispatchNow(new SavePodcast);
}

Personally I consider this trait rather useless, but some I think is there for compatibility reasons. In any case, there is no harm or noticeable performance impact in doing this in your code.

Validating Requests

This one is another helper trait that allows you to validate the incoming data. You are free on how to invoke a Validator instance, but this has handy methods like validating an already instanced Validator, or using a custom “bag of errors” instead of the default one.

This may be unnecessary in some escenarios. If you are using basic logic, consider using the validate() helper method of the $request instance in your Controller, which offers a quick way to validate what’s coming. If not, you may want to use these methods.

Then, it’s necessary or not?

Short answer: it’s not, as long your Controller is simple.

For example, you can make a “vanilla” Controller that is just a plain class that doesn’t use middlewares, authorization, dispatching, nor validation helpers. If that’s the case, you’re done. Or you can extend the default Illuminate\Routing\Controller and set some middlewares for selected methods.

This also applies on Invokable Controllers. No need to extend your Application Controller, or even the Base Controller at all.

Personally I haven’t found noticeable performance impact when using OPCache between a fully-extended Controller and a simple class, doing exactly the same. But you do you, and make benchmarks in case it does impact your system.

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

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