11

Normally I put the logic in the service classes without using repository, for example, something like this:

namespace App\ProjectName\Profile;

use App\User;

class AccountService
{
    private $userModel;

    public function __construct(User $userModel)
    {
        $this->userModel = $userModel;
    }

    public function detail()
    {
        $user = \Auth::User();

        return [
            'id'    => $user->id,
            'name'  => $user->name,
            'email' => $user->email,
            'keys'  => $user->keys,
        ];
    }

    public function addKey($name, $key)
    {
        return $this->userModel->keys()->create([
            'name' => $name,
            'key'  => $key
        ]);
    }
}

I have seen some example out there, refactored even further by creating repository classes. something like UserController inputs data, sends it to UserCreatorService, which gets the UserRepository which in turn gets the UserModel. It seem UserCreatorService is a repeat of UserRepository?

I'll-Be-Back
  • 10,530
  • 37
  • 110
  • 213

3 Answers3

14

From DDD (Domain Driven Design) the responsibility of a repository is to take care of loading, storing, modifying and deleting an entity on the designated data storage (which may or may not be a database -- it may even be a remote server or just a file).

A service, on the other hand, has (or should have) a very narrow responsibility of performing some useful activity. Each service is instantiated separately and then injected into code in the application layer or above, which acts as a bridge (Bridge pattern). This approach has proven to be very advantageous because it allows to manage the dependencies between otherwise unrelated (uncoupled) code.

Those two definitions and the origin of the concepts shows that they actually are very different things. By pure chance you noticed that a repository and a service have an apparent overlap, but that's due to implementation details or plain misuse. Their responsibilities may under circumstances go hand in hand (giving rise to a collaboration) but they really are orthogonal concepts.

Furthermore, Repositories should arise from a deep layer (Persistance or DAL, Data Access Layer). Services, on the other hand, often are vertical cross-cutting or arise on the application layer.

Through proper layering the differences between repositories and services become even more apparent.

Do not think about them as pure code artifacts you can move around. They are well-defined concepts useful to understand about and design the structure of a system. They decline into actual code only as a consequence of that design.

I hope I succeeded in writing something that clears up some ideas and is not confusing.

pid
  • 11,472
  • 6
  • 34
  • 63
14

There is no definitive answer for your question since the patterns you use highly depend on the project's complexity and needs.

However, a Service and a Repository are two different things. The Repository is a common wrapper for the model and is where you write the queries to the database. IMO you shouldn't add logic here and the sole purpose of a repository is to grab os store data into the database. The advantage of Repositories is the "easiness" to switch to other database systems.

A Service, IMO, is where you add all the application's logic.

For additional information refer to this answer.

Community
  • 1
  • 1
Luís Cruz
  • 14,780
  • 16
  • 68
  • 100
  • Thanks! I will have a look at the Answer.. Is it possible to use PHPUnit of `AccountService` class I have done? – I'll-Be-Back Oct 09 '16 at 17:46
  • @I'll-Be-Back It is possible and is simple given the code you posted. However, this `$user = \Auth::User();` should be removed, and you should have a private variable on the class, that is filled on the `_constructor`. This way, on the PHPunit test (or [codeception]) you could pass a User instance through `Mockery`. – Luís Cruz Oct 09 '16 at 18:00
-1

My project manager said:

We use the Repository Pattern for plain PHP.

Repository pattern is for speaking with database so we need repository pattern for big scale Laravel projects.

for example if you decide to change your database from Mysql to CockroachDB, Laravel Eloquent can not support it, so you have to change all the php codes related to Eloquent in your entire project. but with Repository pattern, you don't need to do that. because you need to connect your repository to Eloquent to directly to database, and if you want to migrate to CockroachDB, you just should change your code in one place and you don't need to change any single line in other part of application.

Services in Laravel can be used to:

1 - short the controller

2 - reusable code with dependancy

3 - some people use services just for curl request to external APIs.

it's up to you how do you like to use it.

Raskul
  • 1,674
  • 10
  • 26