Repository Pattern in Laravel – Clean Code Guide

When your Laravel project grows, controllers start getting messy, business logic gets duplicated, and database queries become hard to manage. This is where the Repository Pattern helps you write clean, maintainable, and scalable code.

In this guide, you’ll learn the repository pattern in Laravel step by step with a real example.


🚀 What is Repository Pattern?

The Repository Pattern is a design pattern that acts as a bridge between your business logic and data layer (database).

Instead of writing queries directly in controllers, you create a repository class that handles all database operations.

👉 In simple words:
Controller → Repository → Model (Database)


❌ Problem Without Repository Pattern

Example of a messy controller:

public function index()
{
    $users = User::where('status', 1)->latest()->get();
    return view('users.index', compact('users'));
}

Problems:

  • Business logic inside controller ❌

  • Hard to reuse ❌

  • Difficult to test ❌


✅ Solution With Repository Pattern

Now we move logic to a repository.


📁 Step 1: Create Repository Interface

Create a contract for your repository.

// app/Repositories/UserRepositoryInterface.php

namespace App\Repositories;

interface UserRepositoryInterface
{
    public function getAllActiveUsers();
    public function findById($id);
    public function create(array $data);
}

📁 Step 2: Create Repository Class

// app/Repositories/UserRepository.php

namespace App\Repositories;

use App\Models\User;

class UserRepository implements UserRepositoryInterface
{
    public function getAllActiveUsers()
    {
        return User::where('status', 1)->latest()->get();
    }

    public function findById($id)
    {
        return User::findOrFail($id);
    }

    public function create(array $data)
    {
        return User::create($data);
    }
}

🔗 Step 3: Bind Interface with Repository

Register binding in a service provider.

// app/Providers/AppServiceProvider.php

use App\Repositories\UserRepository;
use App\Repositories\UserRepositoryInterface;

public function register()
{
    $this->app->bind(UserRepositoryInterface::class, UserRepository::class);
}

🎯 Step 4: Use in Controller (Clean Code)

use App\Repositories\UserRepositoryInterface;

class UserController extends Controller
{
    protected $userRepo;

    public function __construct(UserRepositoryInterface $userRepo)
    {
        $this->userRepo = $userRepo;
    }

    public function index()
    {
        $users = $this->userRepo->getAllActiveUsers();
        return view('users.index', compact('users'));
    }
}

✅ Now controller is clean
✅ Logic is reusable
✅ Easy to test


🔥 Advanced Example (With Filters)

public function getUsers($filters = [])
{
    $query = User::query();

    if (!empty($filters['status'])) {
        $query->where('status', $filters['status']);
    }

    if (!empty($filters['search'])) {
        $query->where('name', 'like', '%' . $filters['search'] . '%');
    }

    return $query->paginate(10);
}

🧠 Benefits of Repository Pattern

  • ✅ Clean and readable controllers

  • ✅ Reusable database logic

  • ✅ Easy unit testing

  • ✅ Decoupled architecture

  • ✅ Scalable for large applications


⚠️ When NOT to Use Repository Pattern

Avoid it if:

  • Your project is small/simple CRUD

  • No complex business logic

  • You’re working solo on a quick project

👉 Over-engineering is also bad.


💡 Pro Tips (Important)

  • Combine Repository with Service Layer for complex apps

  • Use DTOs (Data Transfer Objects) for clean data handling

  • Follow SOLID principles

  • Use Laravel Resources for API responses


🏁 Final Thoughts

The Repository Pattern is not mandatory in Laravel, but for medium to large applications, it becomes extremely powerful.

If you're aiming to become a senior Laravel developer, mastering this pattern is a must.

 

 

Back to Portfolio