Laravel Services Pattern

a class using service pattern might look like this

Starting out Laravel I heard a lot of good advice, particularly on Laracast. But others are confusing, particularly on MVC. The common question is where do you put business logic. You’ll hear that you want to keep your controllers skinny and models thin. What the hell?

Using a service layer is the answer if you dig deeper. But service layers are not exactly covered in the Laravel documentation nor part of any guides and learning modules. But here’s what I understand so far.

Put your extra business logic in a Service class and import it into your controller.

Here’s a good excerpt from Travis Britz on SO.

Services, on the other hand, are an easy way to encapsulate the logic around a component, and they may do more than one thing… Consider if you didn’t store books by inserting them into your database, but instead by posting to an external API. All of these requests share logic for authenticating to the external web service (like adding headers to requests), and your BookRepository class can encapsulate that re-usable logic. You can use this service class inside of scheduled artisan commands, web controllers, api controllers, jobs, middleware, etc. — without repeating code.

P. Ellul shows what this might look like.

What about creating a Services folder under app/, and use Controller dependency injection.

MyService.php

namespace App\Services;

use App\Models\Bar;

class MyService
{
    public function foo(Bar $bar)
    {
       // do things
    }
}

MyController.php

namespace App\Http\Controllers;

use App\Services\MyService;
use App\Models\Bar;

class MyController extends Controller
{
    protected $myService;

    public function __construct(MyService $myService)
    {
        $this->myService = $myService;
    }

    public function handleRequest(Bar $bar)
    {
        $this->myService->foo($bar);
    }
}

As you can see, it’s a simple class abstraction and instantiating the class in the controller construct. If it’s not a third-party service you could bypass the construct and call a new() class. And it’s not a problem to create your own Services folder and store it there.

7 thoughts on “Laravel Services Pattern”

  1. Thanks for this. It is a simple concept (and simple implementation), but I am having to learn Laravel after working in ASP.net MVC for years, so it helps to just have someone point out the obvious.

    Reply
  2. it seems a bit messy to me as you end up with code like this:
    $this->barService->foo($bar);

    Coming from a project using the Yii framework where we used a “thin” base model and then a “Service” model which inherits the base model. so this would end up with
    app > Models
    Bar.php – service class which inherits Bar model
    app > Models > Base
    BarBase.php – “thin” model

    I can see that this might be confusing so you could reverse it:
    app > Models
    Bar.php – “thin” model
    app > Services
    BarService.php – service class which inherits Bar model
    namespace App\Services;
    use App\Models\Bar;
    class BarService extends Bar
    {
    public function foo()
    {
    // do things
    }
    }

    then your controller could instantiate the service class instead:

    public function handleRequest(BarService $bar)
    {
    $bar->foo();
    }

    Would that be an OK design pattern?

    Reply

Leave a Comment