Single Method Controllers in Laravel
Tags: laravel, php
Published: 2019-07-02 07:39:16

---
title: Single Method Controllers in Laravel
published: true
description: Implementing single method controllers in Laravel
tags: laravel, php
---

We all agree that methods and function should do one thing only. We call this *Single Responsibility Principle*. 

However, the fact that methods should follow SRP does not imply that we should have a controller housing many (almost) independent methods which would result in a very unstructured business logic.

Having a single method controller is a fantastic way of upholding the *Single Responsibility Principle*. For example, take a look at the controller below

```php
namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Plan;

class PlansController extends Controller
{
    public function index()
    {
    	//Logic to Get All Plans
    }

    public function create(Request $request)
    {
        //Logic to create new Plan
    }

    
    public function inviteUser(Request $request)
    {
        //Logic to invite user to plan
    }
}

```

The first thought that would come to mind is that the `inviteUser` method does not belong to this controller. We should have something like `InviteUserController`. And that is absolutely what we should do.

From the name of this controller, it is expected to do one thing only - Invite a user to a specific plan. 

So we can simply have something like

```php
namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class InviteUserController extends Controller
{
    
    public function inviteUser(Request $request)
    {
        //Logic to invite user to plan
    }
}
```

and we should be done right? - Well how about if this could be done better? - Introducing Magic Method `__invoke` :)

PHP has several Magic methods. Magic methods are named with two underscores at the start, which get called automatically when a particular event happens.

The `__invoke()` method gets called when the object is called as a function. When you declare it, you say which arguments it should expect. Here's a trivially simple example:

```php
class Human {

  public function __invoke() {

    echo "Sophisticated creature";
  }
}
```

We can instantiate a Human object, and then just use it like a function:

```php
$victor = new Human();
$victor(); // Sophisticated creature
```

With this understanding, we can simply rename the `inviteUser` method of the `InviteUserController` to `__invoke` as seen below

```php
namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class InviteUserController extends Controller
{
    
    public function __invoke(Request $request)
    {
        //Logic to invite user to plan
    }
}

```

And in the routes file we would no more use the string literal convention to map a route to this controller instead we add the class like

```php
use App\Http\Controllers\Api;

Route::get('/invite', InviteUserController::class)
```

Let me know what you think about single method controllers!

Credit: [lornajane](https://lornajane.net/posts/2012/phps-magic-__invoke-method-and-the-callable-typehint)

_PS: This is my first blog post on Dev.to_