I spend the whole day trying to wrap my head around repositories in Laravel and just when I thought I understood them, I found another point of criticism. I read Shawn's post, this discussion here, and for sure, watched the videos on Laracasts.
Let me make a bold statement:
The original idea of repositories is pointless within Laravel, if you use Eloquent for all your models.
In the video "Repositories Simplified", the idea is to separate the controller from the ORM. So instead of doing
$orders = Order::all();
You'd do:
$orders = $orderRepository->all();
If I use an interface, I can now implement my DbRepository or ArrayRepository, RedisRepository or whatnot. But what happens inside your repository? You call:
$this->model->all();
Such a repository requires an Eloquent model and won't work without one. So, if you truly want to swap out the implementation details of your persistence layer, you also need a model that doesn't depend on Eloquent.
But if you use a model without Eloquent, why would you use Laravel at all? It seems like L5's Model class makes heavy use of Eloquent features, although it's probably possible to create your own base model.
Anyways, try a thought experiment. If things like these:
Order::all();
Order::find(1);
Order::create(...);
were just a different way to write
$orderRepository->all();
$orderRepository->find(1);
$orderRepository->create(...);
all of a sudden, Eloquent just looks like a repository. Also, try to read Shawn's post again with this though experiment in mind:"Using the static function of a model is the same as a repository, e. g. it means we're working with the collection of this model". Then suddenly, it seems that there's no need to use repositories at all as long as your models rely on Eloquent.
For sure, this doesn't mean that one shouldn't keep his controllers super-slim, but the same can be achieved with Command Bus or Services.
Again, my point is: If your models all extend L5's Model class or use Eloquent, a repository is redundant.
Or to put it another way: If you don't separate your models from Eloquent, your repositories don't achieve any abstractions at all, because the dependency is still there.
Comments?