Skip to main content

Repository Design Pattern

Introduction#

The repository paatern is one of the most powerful patterns for handling data either in storing, deleting or fetching data from database.

In Mongez, the repository provides a simple way to handle advanced and complex usage when dealing with data.

In theory, the repsotiroy design pattern mainly works with models to handle data from and to database, as it is used as an additional layer between top layers like controllers and models.

Repository Structure#

Each repository MUST implement HZ\Illuminate\Mongez\Contracts\Repositories\RepositoryInterface which contains the following methods:

RepositoryInterface
<?php
namespace HZ\Illuminate\Mongez\Contracts\Repositories;
use Illuminate\Support\Collection;
interface RepositoryInterface
{
/**
* Create new record
*
* @param \Illuminate\Http\Request|array $data
* @return Illuminate\Database\Eloquent\Model
*/
public function create($data);
/**
* Update a the given record id
*
* @param int id
* @param \Illuminate\Http\Request|array $data
* @return Illuminate\Database\Eloquent\Model
*/
public function update(int $id, $data);
/**
* Delete a specific record
*
* @param int id
* @return bool
*/
public function delete(int $id): bool;
/**
* Return List of records
*
* @param array options
* @return Illuminate\Support\Collection
*/
public function list(array $option): Collection;
/**
* Get a specific record with full details
*
* @param int id
* @return mixed
*/
public function get(int $id);
/**
* Determine whether the given value exists
*
* @param mixed $value
* @param string $column
* @return bool
*/
public function has($value, string $column): bool;
}

Thankfully, Mongez is shipped with Repository Managers that handles most of the prior methods with robust features to organize your operations.

Repository Initiation#

Repositories declartions are stored on the Mongez Configurations Repositories Section, each repository has an alias for quicker usage instead of injecting the repository class.

tip

All repositories are singletons, which means when you call any repository from anywhere, it will create only single instance of it.

Using Repositories#

Repositories can be called with 5 ways

1. Using Service Containers#

Repositories can be injected into any method using Laravel Service Container or IoC.

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Modules\Users\Repositories\UsersRepository;
class UsersControllers extends Controller
{
/**
* Get users
*
* @param UsersRepository $repository
* @param Request $request
* @return Response
*/
public function index(UsersRepository $repository, Request $reuqest)
{
$users = $repository->list([
'name' => $request->name,
]);
}
}
info

This is not the prefered way to use repositories, it can be used though.

2. Using repo function#

The repo(string $repositoryAlais): RepositoryInterface can be used from anywhere in the application.

routes/api.php
<?php
Route::delete('/users/{id}', function ($id) {
repo('users')->delete($id);
return [
'success' => true,
];
});

3. Using ApiController#

Any controller extends ApiController class, a REPOSITORY_NAME constanct can be declared in the derived class with the repository alias name, then from any method the repository property can be used as a reference to the repository instance.

UsersControllers.php
<?php
namespace App\Modules\Users\Controllers\Site;
use Illuminate\Http\Request;
use HZ\Illuminate\Mongez\Managers\ApiController;
class UsersControllers extends ApiController
{
/**
* Repository name
*
* @var string
*/
protected const REPOSITORY_NAME = 'users';
/**
* {@inheritDoc}
*/
public function index(Request $request)
{
$options = [
'status' => 'active'
];
return $this->success([
'records' => $this->repository->list($options),
]);
}
}
tip

This is the recommended way if you're extending any Mongez Base Controller for using repositories.

3. Using AdminApiController#

Similar to the ApiController except that the repository name is in the controller options array.

UsersControllers.php
<?php
namespace App\Modules\Users\Controllers\Admin;
use Illuminate\Http\Request;
use HZ\Illuminate\Mongez\Managers\AdminApiController;
class UsersControllers extends AdminApiController
{
/**
* Controller info
*
* @var array
*/
protected $controllerInfo = [
'repository' => 'users',
'listOptions' => [
'select' => [],
'filterBy' => [],
'paginate' => null, // if set null, it will be automated based on repository configuration option
],
'rules' => [
'all' => [],
'store' => [],
'update' => [],
],
];
/**
* Active/Deactive user account
*
* @param int $id
* @param Request $request
* @return Response
*/
public function toggleUserActivation($id, Request $request)
{
$user = $this->repository->getModel($id);
if (! $user) {
return $this->notFound('User is not listed in our database records.');
}
$this->repository->toggleActivation($user, (bool) $request->activate);
return $this->success();
}
}

5. Using Repositry Trait#

Another way of using repositories is by using Repository Trait.

app\Http\Controllers\UsersControllers.php
<?php
namespace App\Http\Controllers;
use HZ\Illuminate\Mongez\Traits\RepositoryTrait;
class UsersControllers extends Controller
{
use RepositoryTrait;
/**
* {@inheritDoc}
*/
public function index()
{
// now use the property to access the repository and append `Repository` keyword after the repository alias
$users = $this->usersRepositry->list([
'status' => 'active',
]);
}
}

This will allow you to use any repository from the class that injects the repositry trait.

Generating new repository#

To create a new repository, use the following command line:

php artisan engez:repository usersGroups --module=users --string=name --bool=published --uploads=avatar

This will create a new repository classes located in the Users module Repositories directory.

Repository Simpler Structure#

All inherited repositories from any Repository Maanger have mere constants and methods for quicker development.