Laravel: Invokable Controllers

The most common controller in Laravel has an index, store and a destroy method. Maybe there is also a need for additional methods, such as update, show or a method that could start a complicated action. And many times it makes sense all of these methods to inhabit the same controller. But there is another case.

Sometimes it makes sense to have a controller that only has one method, for example a controller that will download a file. In this case, you can use an Invokable controller. An invokable controller uses the PHP magic method __invoke that allows an object to be called as a function.


1. How to create an invokable controller

Laravel, the advanced framework that it is, has a special command to create an invokable controller.


php artisan make:controller DownloadFileController --invokable
                                        

This command will create the following controller:


namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DownloadFileController extends Controller
{
    /**
     * Handle the incoming request.
     */
    public function __invoke(Request $request)
    {

        return "Download file...";
    }
}
                                        

2. Routing

The invokable controller can make the routing cleaner due to the lack of defining a method name.


use App\Http\Controllers\DownloadFileController;
use Illuminate\Support\Facades\Route;

// No need for ['DownloadFileController', 'download']
Route::post('/download/file', DownloadFileController::class);
                                        

When to use an invokable controller

Single Responsibility Principle: An invokable controller is a good choice when you need to create a controller that only has one method, adhering to the Single Responsibility Principle.

Clean Routing: When you need to have a clean routing file.


When to avoid an invokable controller

When you have the typical CRUD controller. It doesn't make sense to have an invokable controller for each of the actions.