Use case
- We have Post resource
- Need to implement controller to support APIs for these features :
Get all posts
Paginate posts
Find posts with condition
Find post by id
Caching APIs to improve performance
Preparation
- Post model (database driver can be MySQL/ PostgreSQL/ SQLite/ SQL Server)
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $table = 'posts';
}
- Contract
<?php
namespace App\Http\Contracts;
interface RepositoryInterface
{
/**
* Retrieve all data of repository
*
* @param array $columns
*
* @return mixed
*/
public function all($columns = ['*']);
/**
* Retrieve all data of repository, paginated
*
* @param null $limit
* @param array $columns
*
* @return mixed
*/
public function paginate($limit = null, $columns = ['*']);
/**
* Find data by multiple fields
*
* @param array $where
* @param array $columns
*
* @return mixed
*/
public function findWhere(array $where, $columns = ['*']);
/**
* Find data by id
*
* @param $id
* @param array $columns
*
* @return mixed
*/
public function find($id, $columns = ['*']);
}
Implementation Details
Newbie/Beginner/Fresher/Intern level
<?php
namespace App\Http\Controllers;
use App\Http\Contracts\RepositoryInterface;
use App\Post;
class PostController extends Controller implements RepositoryInterface
{
protected $post;
public function __construct(Post $post)
{
$this->post = $post;
}
public function all($columns = ['*'])
{
return $this->post->all($columns);
}
public function paginate($limit = null, $columns = ['*'])
{
return $this->post->paginate($limit, $columns);
}
public function find($id, $columns = ['*'])
{
return $this->post->find($id, $columns);
}
public function findWhere(array $where, $columns = ['*'])
{
foreach ($where as $field => $value) {
if (is_array($value)) {
list($field, $condition, $val) = $value;
$this->post = $this->post->where($field, $condition, $val);
} else {
$this->post = $this->post->where($field, '=', $value);
}
}
return $this->post->get($columns);
}
}
Database Repository/ Junior Level
<?php
namespace App\Http\Controllers;
use App\Http\Contracts\RepositoryInterface;
use App\Post;
class DbPostRepository implements RepositoryInterface
{
private $post;
public function __construct(Post $post)
{
$this->post = $post;
}
public function all($columns = ['*'])
{
return $this->post->all($columns);
}
public function paginate($limit = null, $columns = ['*'])
{
return $this->post->paginate($limit, $columns);
}
public function findWhere(array $where, $columns = ['*'])
{
foreach ($where as $field => $value) {
if (is_array($value)) {
list($field, $condition, $val) = $value;
$this->model = $this->post->where($field, $condition, $val);
} else {
$this->model = $this->post->where($field, '=', $value);
}
}
return $this->post->get($columns);
}
public function find($id, $columns = ['*'])
{
return $this->post->find($id, $columns);
}
}
class DbPostController extends Controller
{
private $dbPostRepository;
public function __construct(DbPostRepository $dbPostRepository)
{
$this->dbPostRepository = $dbPostRepository;
}
public function all($columns = ['*'])
{
return $this->dbPostRepository->all($columns);
}
public function paginate($limit = null, $columns = ['*'])
{
return $this->dbPostRepository->paginate($limit, $columns);
}
public function findWhere(array $where, $columns = ['*'])
{
return $this->dbPostRepository->findWhere($where, $columns);
}
public function find($id, $columns = ['*'])
{
return $this->dbPostRepository->find($id, $columns);
}
}
Caching Repository/ Senior Level
<?php
namespace App\Http\Controllers;
use App\Http\Contracts\RepositoryInterface;
use Illuminate\Contracts\Cache\Repository as CacheRepository;
class CachePostRepository implements RepositoryInterface
{
private $dbPostRepository;
private $cacheRepository;
public function __construct(DbPostRepository $dbPostRepository, CacheRepository $cacheRepository)
{
$this->dbPostRepository = $dbPostRepository;
$this->cacheRepository = $cacheRepository;
}
public function getCacheMinutes()
{
return config('repository.cache.minutes', 30);
}
public function getCacheKey($method, $args = null)
{
$request = app('Illuminate\Http\Request');
$args = serialize($args);
$criteria = $this->serializeCriteria();
$key = sprintf('%s@%s-%s', get_called_class(), $method, md5($args . $criteria . $request->fullUrl()));
return $key;
}
public function all($columns = ['*'])
{
$key = $this->getCacheKey('all', func_get_args());
$minutes = $this->getCacheMinutes();
return $this->cacheRepository->remember($key, $minutes, function () use ($columns) {
return $this->dbPostRepository->all($columns);
});
}
public function paginate($limit = null, $columns = ['*'])
{
$key = $this->getCacheKey('paginate', func_get_args());
$minutes = $this->getCacheMinutes();
return $this->cacheRepository->remember($key, $minutes, function () use ($limit, $columns) {
return $this->dbPostRepository->paginate($limit, $columns);
});
}
public function findWhere(array $where, $columns = ['*'])
{
$key = $this->getCacheKey('findWhere', func_get_args());
$minutes = $this->getCacheMinutes();
return $this->cacheRepository->remember($key, $minutes, function () use ($where, $columns) {
return $this->dbPostRepository->findWhere($where, $columns);
});
}
public function find($id, $columns = ['*'])
{
$key = $this->getCacheKey('find', func_get_args());
$minutes = $this->getCacheMinutes();
return $this->cacheRepository->remember($key, $minutes, function () use ($columns) {
return $this->dbPostRepository->all($columns);
});
}
}
class CachePostController extends Controller
{
private $cachePostRepository;
public function __construct(CachePostRepository $cachePostRepository)
{
$this->cachePostRepository = $cachePostRepository;
}
public function all($columns = ['*'])
{
return $this->cachePostRepository->all($columns);
}
public function paginate($limit = null, $columns = ['*'])
{
return $this->cachePostRepository->paginate($limit, $columns);
}
public function findWhere(array $where, $columns = ['*'])
{
return $this->cachePostRepository->findWhere($where, $columns);
}
public function find($id, $columns = ['*'])
{
return $this->cachePostRepository->find($id, $columns);
}
}
Top comments (0)