Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jordan.dobrev.88@gmail.com's avatar

Repository pattern and validation

Hi there,

After watching the last Repository trap cast, I got a little bit confused again.

So far I have a relatively big Laravel project. I am trying to use the repository pattern but I don't think I am doing it the right way. So far I follow this convention:

Model -> eloquent model MorelRepository -> interface extending a Repository contract ModelRepositoryEloquent -> implementation of the ModelRepository interface. (where Moldel is Model name- Customer,Comment,etc)

Each model has a repository and based on the the type of the repository I have extra interfaces and traits that I implement/use (like BelongsToCustomer). On top of that each repository has its own validate method.

Lets assume I have a Comment model that belongs to a Customer model

To save a Comment from my within controller I have to do:

$commentRepository->validate($request->all());
$commentRepository->saveForCustomer($customer, $request->all());

Looked ok to me but recently I found out that its wrong.

  1. Validate should not be there - the repository pattern should only care about data persistence and extraction.
  2. I should not have repo per model - I should use Customer repository and save a comment like this
$customerRepository->addComment($customer, $comment);

How do I access all comments then? Do I need comment repository too if I want to do that?

Am I right and if so where do I put data and business logic validations? Should I make separate Validation service for each model? Should I place them in the models(isn't that destroying my design pattern)?

0 likes
12 replies
sid405's avatar

@LPMadness I think one of the important things to take from Jeff's latest video is : Depends.

Basically don't do things because you're supposed to, do them because you need them.

There is no golden rule in any of this unfortunately. Imo.

2 likes
jekinney's avatar
Level 47

@sid405 lol, great post!

I implore you to find the repository bible @LPMadness! Every pattern I have researched has about as many "ways" of doing it as results.

With that said, I don't validate in a repo. I go shortest route. So that's in the controller or a form request. But that's just me. I do advise to be consistent with your decision. For example you decide to validate user registration in your repo and a blog comment in your controller, six months later good luck figuring it all out.

2 likes
sid405's avatar

@jekinney Indeed. Form request most of the time for me. By the time i hit the repo, if i do so, i don't wanna worry about validation.

martinbean's avatar

@LPMadness Yeah, validation doesn’t belong in the repository. There’s nothing stopping you validating data before passing it to the repository though. Say, in a form request class (if you need to re-use it in multiple places) or using the validate() method available in controllers.

bencarter78@hotmail.com's avatar

I was one of the people who, as soon as seeing the early repository videos on here, thought it was the 'proper way' and like many over used this pattern. I have since begun to learn when to use this.

One thing I would say though is that unless you do use it (and in my case over use it) then I would have never have had the experience of knowing when it was overkill.

Over use of most things can be a bad thing, but on a positive, you do learn a lot about it.

jordan.dobrev.88@gmail.com's avatar

@martinbean form requests are fine but unfortunately they don't fit perfectly in what I want to do. I have inserts and updates in many places and they are located in different places in my request array. Therefore I considered moving all validations in a separate App\Validation namespace so I can reuse them differently in different places. I can also add additional methods and functionality to each validation class.

<?php

namespace App\Validation;

use Illuminate\Http\Request;

/**
 * Class Validation
 *
 * @package App\Validation
 */
abstract class Validation
{
    /**
     * @var array ignore
     */
    protected $ignore = [];

    /**
     * Specify laravel style rules
     *
     * @return array
     */
    abstract protected function rules();

    /**
     * Specify rules you want to ignore for the following validation
     *
     * @param ...$ignore
     *
     * @return $this
     */
    public final function ignore(...$ignore)
    {
        $this->ignore = $ignore;

        return $this;
    }

    /**
     * Perform validation
     *
     * @param array|Request $input
     *
     * @throws \App\Exceptions\Errors
     */
    public final function run($input)
    {
        if ($input instanceof Request) {
            $input = $input->all();
        }

        if (!is_array($input)) {
            $input = (array)$input;
        }

        if (method_exists($this, 'before')) {
            $this->before($input);
        }

        validate($input, $this->rules());

        if (method_exists($this, 'after')) {
            $this->after($input);
        }
    }
}
1 like
pmall's avatar

@LPMadness Can you explain why you cant use form requests to validate your input ? This is unclear.

jordan.dobrev.88@gmail.com's avatar

Form requests work directly with the Request objects, and that is not the best way to deal with validations.

Lets assume I have a customer and comments

In my app I have 3 different ways to push comments for customers:

  1. CommentController->save($input) - single comment
  2. RestCommentController->saveMany($input) - batch of comments
  3. RestCustomerController->store($input) -> this input has 'comments' key and I have multiple validations I have to perform. I don't need to validate customer_id here so I want to ignore this check.

So If I want to do that I need 3 different FormRequests for each scenario with a lot of code duplication. Is there a way I can force FormRequests to use data from specific place in my input? If no I see no better way to deal with it so far.

pmall's avatar

So you have three forms to save a comment/many comments ?

martinbean's avatar

@LPMadness I don’t think a validation class where you arbitrarily “ignore” validation rules is a good idea. What happens if you forget to ignore a rule for a particular scenario? What happens if you introduce a fourth way to add a comment? You’re going to have this big validation class that’s fragile because you’re tried to make it work for multiple situations in an attempt to adhere to the “single responsibility principle”.

Think about adding a comment: the user (whether that’s a website visitor, an administrator, or API user) issues a request to create a comment. There’s the name of your form request class: CreateCommentRequest.

In terms of validating different fields in different contexts, you might want to look at the “Conditionally Adding Rules” section in the Laravel documentation.

jordan.dobrev.88@gmail.com's avatar

@pmall I have one HTML form and 2 other ways of attaching comments to a customer in the API functionality.

@martinbean I agree but unfortunately in my case it is not nice because the app is quite big and I will end up with 1000 form requests. It also causes headache when you want to add additional field/validation for a specific field. I like the idea of having basic validation and adding conditional checks, but then we have to do extra work which is not that different that ignoring validations.

pmall's avatar

I would go with three form requests in this case. It will worth it in the long run. Don't over-dry your code.

It is more important to have understandable code than to avoid repeating some validation rules.

2 likes

Please or to participate in this conversation.