A comprehensive Laravel package that implements the Repository and Service Layer design patterns, providing a clean and maintainable way to interact with your Eloquent models. This package promotes separation of concerns, making your code more testable, organized, and following SOLID principles.
- Repository Pattern Implementation - Clean abstraction layer between your controllers and models
- Service Layer Pattern - Business logic separation from controllers
- Artisan Commands - Generate repositories and services with simple commands
- Interface-Based - Follows dependency inversion principle
- Performance Optimized - Built with Laravel best practices
- Rich Query Methods - Comprehensive set of query methods out of the box
- PHP >= 8.0
- Laravel >= 9.0
You can install the package via Composer:
composer require longaodai/laravel-repository
Publish the configuration file:
php artisan vendor:publish --tag=laravel-repository
This will create a config/repository.php
file where you can customize package settings.
Generate a complete repository and service for your model:
php artisan make:repository User
--model=ModelName
: Specify the model class name--force
: Overwrite existing files
Repository Interface ........... App\Repositories\User\UserRepositoryInterface
Repository Implementation ...... App\Repositories\User\UserEloquentRepository
Service Interface .............. App\Services\User\UserServiceInterface
Service Implementation ......... App\Services\User\UserService
The service provider registration depends on your Laravel version and configuration:
If your config/repository.php
has 'binding_mode' => 'provider'
(default), you must register the service providers.
Add the generated service providers to your bootstrap/providers.php
(only once after running the first make repository command):
<?php
return [
App\Providers\AppServiceProvider::class,
// ... other providers
// Add these lines
App\Providers\RepositoryServiceProvider::class,
App\Providers\InternalServiceProvider::class,
];
If your config/repository.php
has 'binding_mode' => 'attribute'
and you're using Laravel 12+, you can skip the service provider registration entirely. The package will automatically register bindings using PHP attributes.
Configuration Example:
// config/repository.php
return [
'binding_mode' => 'attribute', // Change to 'attribute' for Laravel 12+
// ... other config
];
Inject and use the service in your controllers:
<?php
namespace App\Http\Controllers;
use App\Services\User\UserServiceInterface;
use Illuminate\Http\Request;
class UserController extends Controller
{
protected $userService;
public function __construct(UserServiceInterface $userService)
{
$this->userService = $userService;
}
/**
* Display a paginated list of users
*/
public function index(Request $request)
{
// Get paginated list with optional filters
$users = $this->userService->getList([
'name' => $request->get('name'),
]);
return response()->json($users);
}
/**
* Store a new user
*/
public function store(Request $request)
{
$userData = collect([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
]);
$user = $this->userService->create($userData);
return response()->json($user, 201);
}
/**
* Display the specified user
*/
public function show($id)
{
$user = $this->userService->find(['id' => $id]);
if (!$user) {
return response()->json(['message' => 'User not found'], 404);
}
return response()->json($user);
}
/**
* Update the specified user
*/
public function update(Request $request, $id)
{
$updateData = [
'name' => $request->name,
'email' => $request->email,
];
$user = $this->userService->update($updateData, ['id' => $id]);
return response()->json($user);
}
/**
* Remove the specified user
*/
public function destroy($id)
{
$deleted = $this->userService->destroy(['id' => $id]);
return response()->json(['deleted' => $deleted]);
}
}
Add custom methods to your repository:
<?php
namespace App\Repositories\User;
use App\Models\User;
use LongAoDai\LaravelRepository\Eloquent\BaseRepository;
class UserEloquentRepository extends BaseRepository implements UserRepositoryInterface
{
public function model(): string
{
return User::class;
}
/**
* Hook for filtering queries.
*
* @param RepositoryResponse $params
*
* @return static
*/
protected function filter(RepositoryResponse $params): static
{
if (!empty($params->get('id'))) {
$this->method('where', $this->table . '.id', $params->get('id'));
}
if (!empty($params->get('name'))) {
$this->method('where', $this->table . '.name', $params->get('name'));
}
if (!empty($params->get('status'))) {
$this->method('where', $this->table . '.status', $params->get('status'));
}
if (!empty($params->option('with_post'))) {
$this->method('with', ['posts' => function ($query) {
return $query->select('id', 'name');
}]);
}
return parent::filter($params);
}
/**
* Hook for filtering update.
*
* @param RepositoryResponse $params
*
* @return static
*/
protected function mask(RepositoryResponse $params): static
{
if (!empty($params->option('id'))) {
$this->method('where', $this->table . '.id', $params->option('id'));
}
return parent::mask($params);
}
}
Implement complex business logic in services:
<?php
namespace App\Services\User;
use App\Repositories\User\UserRepositoryInterface;
use App\Notifications\WelcomeNotification;
use Illuminate\Support\Facades\DB;
class UserService implements UserServiceInterface
{
public function __construct(UserRepositoryInterface $repository)
{
$this->userRepository = $repository;
}
/**
* Create a new user with welcome notification
*/
public function createUserWithWelcome($userData)
{
return DB::transaction(function () use ($userData) {
// Create user
$user = $this->userRepository->create($userData);
// Send welcome notification
$user->notify(new WelcomeNotification());
// Log user creation
logger('New user created', ['user_id' => $user->id]);
return $user;
});
}
/**
* Get users with specific business logic
*/
public function getActiveUsersWithPosts($data, $options)
{
return $this->userRepository->all(
[
'status' => $data['status'],
], [
'with_post' => true,
]
);
}
}
The base repository provides these methods out of the box:
Method | Description | Example |
---|---|---|
all() |
Get all records | $service->all() |
getList() |
Get paginated list with filters | $service->getList(['status' => 'active'], ['per_page' => 10]) |
find() |
Find by id | $service->find(['id' => 1]) |
first() |
Get first record by conditions | $service->first(['status' => 'active']) |
create() |
Create new record | $service->create(['name' => 'John']) |
update() |
Update records | $service->update(['name' => 'Jane'], ['id' => 1]) |
updateOrCreate() |
Update or create record | $service->updateOrCreate(['name' => 'Test'], ['email' => 'test@example.com']) |
destroy() |
Delete records | $service->destroy(['id' => 1]) |
// Get all users
$users = $userService->all();
// Get paginated list with search
$users = $userService->getList([
'status' => 'active'
], ['per_page' => 20,]);
// Find specific user
$user = $userService->find(['id' => 1]);
// Get first user with conditions
$activeUser = $userService->first(['status' => 'active']);
$user = $userService->first(['email' => 'user@example.com']);
// Create new user
$newUser = $userService->create(collect([
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => bcrypt('password123'),
'status' => 'active'
]));
// Update user
$updatedUser = $userService->update([
'name' => 'John Smith', // data to update
], ['id' => 1]); // conditions
// Update or create user
$user = $userService->updateOrCreate(
collect(['name' => 'Jane Doe', 'status' => 'active']) // data to update/create
collect(['email' => 'jane@example.com']), // conditions
);
// Delete user
$deleted = $userService->destroy(['id' => 1]);
// Delete multiple users
$deleted = $userService->destroy(['status' => 'inactive']);
// ❌ Bad - Logic in controller
public function store(Request $request)
{
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
]);
$user->notify(new WelcomeNotification());
return response()->json($user);
}
// ✅ Good - Logic in service
public function store(Request $request)
{
$user = $this->userService->createUserWithWelcome($request->validated());
return response()->json($user);
}
// ✅ Good
public function __construct(UserServiceInterface $userService)
{
$this->userService = $userService;
}
// ❌ Bad
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
If you discover any security-related issues, please email vochilong.work@gmail.com instead of using the issue tracker. LongAoDai
The MIT License (MIT). Please see License File for more information.
If you find this package helpful, please consider:
- Starring the repository
- Reporting any bugs you encounter
- Suggesting new features
- Improving documentation