MVC (Laravel) where to add logic

I think all patterns / architectures that you present are very useful as long as you follow the SOLID principles.

For the where to add logic I think that it’s important to refer to the Single Responsibility Principle. Also, my answer considers that you are working on a medium / large project. If it’s a throw-something-on-a-page project, forget this answer and add it all to controllers or models.

The short answer is: Where it makes sense to you (with services).

The long answer:

Controllers: What is the responsibility of Controllers? Sure, you can put all your logic in a controller, but is that the controller’s responsibility? I don’t think so.

For me, the controller must receive a request and return data and this is not the place to put validations, call db methods, etc..

Models: Is this a good place to add logic like sending an welcome email when a user registers or update the vote count of a post? What if you need to send the same email from another place in your code? Do you create a static method? What if that emails needs information from another model?

I think the model should represent an entity. With Laravel, I only use the model class to add things like fillable, guarded, table and the relations (this is because I use the Repository Pattern, otherwise the model would also have the save, update, find, etc methods).

Repositories (Repository Pattern): At the beginning I was very confused by this. And, like you, I thought “well, I use MySQL and thats that.”.

However, I have balanced the pros vs cons of using the Repository Pattern and now I use it. I think that now, at this very moment, I will only need to use MySQL. But, if three years from now I need to change to something like MongoDB most of the work is done. All at the expense of one extra interface and a $app->bind(«interface», «repository»).

Events (Observer Pattern): Events are useful for things that can be thrown at any class any given time. Think, for instance, of sending notifications to a user.
When you need, you fire the event to send a notification at any class of your application. Then, you can have a class like UserNotificationEvents that handles all of your fired events for user notifications.

Services: Until now, you have the choice to add logic to controllers or models. For me, it makes all sense to add the logic within Services. Let’s face it, Services is a fancy name for classes. And you can have as many classes as it makes sense to you within your aplication.

Take this example: A short while ago, I developed something like the Google Forms. I started with a CustomFormService and ended up with CustomFormService, CustomFormRender, CustomFieldService, CustomFieldRender, CustomAnswerService and CustomAnswerRender. Why? Because it made sense to me. If you work with a team, you should put your logic where it makes sense to the team.

The advantage of using Services vs Controllers / Models is that you are not constrained by a single Controller or a single Model. You can create as many services as needed based on the design and needs of your application. Add to that the advantage of calling a Service within any class of your application.

This goes long, but I would like to show you how I have structured my application:

app/
    controllers/
    MyCompany/
        Composers/
        Exceptions/
        Models/
        Observers/
        Sanitizers/
        ServiceProviders/
        Services/
        Validators/
    views
    (...)

I use each folder for a specific function. For example the Validators directory contains a BaseValidator class responsible for processing the validation, based on the $rules and $messages of specific validators (usually one for each model). I could as easily put this code within a Service, but it makes sense to me to have a specific folder for this even if it is only used within the service (for now).

I recommend you to read the following articles, as they might explain things a little better to you:

Breaking the Mold by Dayle Rees (author of CodeBright): This is where I put it all together, even though I changed a few things to fit my needs.

Decoupling your code in Laravel using Repositories and Services by Chris Goosey: This post explains well what is a Service and the Repository Pattern and how they fit together.

Laracasts also have the Repositories Simplified and Single Responsibility which are good resources with practical examples (even though you have to pay).

Leave a Comment