DEV Community

Cover image for Caching in laravel with repository and proxy design patterns
Mohammad Reza
Mohammad Reza

Posted on • Edited on

Caching in laravel with repository and proxy design patterns

What is the story

Think that you have a blog and you want to show top ten posts in your index page, and imagine that you have many posts in your site, in this scenario you should send a query to your database per user who open your first page ...

so what can you do ?

You can fetch it every hour f.e. and save it and then serve it to the user without need to use db

lets start

step one

First define your route
routes/web.php

<?php

use Illuminate\Support\Facades\Route;

Route::get('/', 'PostController@index');
Enter fullscreen mode Exit fullscreen mode

step two

Define your controller

<?php

namespace App\Http\Controllers;

use App\Repositories\Post\PostRepositoryInterface;

class PostController extends Controller
{
    private $postRepository;
    public function __construct(PostRepositoryInterface $postRepository)
    {
        $this->postRepository = $postRepository;
    }

    public function index()
    {
        return $this->postRepository->getTopTen();
    }
}

Enter fullscreen mode Exit fullscreen mode

step three

Make Repository directory in you app directory and fill it like this

└── Post
    ├── PostCachedRepository.php
    ├── PostRepositoryInterface.php
    └── PostRepository.php
Enter fullscreen mode Exit fullscreen mode

PostCachedRepository.php

<?php

namespace App\Repositories\Post;

use Illuminate\Support\Facades\Cache;

class PostCachedRepository implements PostRepositoryInterface
{
    private $postRepository;
    public function __construct(PostRepository $postRepository)
    {
        $this->postRepository = $postRepository;
    }

    public function getTopTen()
    {
        $value = Cache::remember('topTen', 3600, function () {
            return $this->postRepository->getTopTen();
        });

        return $value;
    }
}

Enter fullscreen mode Exit fullscreen mode

PostRepositoryInterface.php

<?php

namespace App\Repositories\Post;

interface PostRepositoryInterface {
    public function getTopTen();
}
Enter fullscreen mode Exit fullscreen mode

PostRepository.php

<?php

namespace App\Repositories\Post;

use App\Post;

class PostRepository implements PostRepositoryInterface
{
    public function getTopTen()
    {
        return Post::orderBy('star', 'desc')->take(10)->get();
    }
}

Enter fullscreen mode Exit fullscreen mode

step four

your post model and migration file
app/Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model {}

Enter fullscreen mode Exit fullscreen mode

And migration file

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title', 100);
            $table->text('text');
            $table->integer('star');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Enter fullscreen mode Exit fullscreen mode

step five

Set cache driver config
Go to .env file and change CACHE_DRIVER to CACHE_DRIVER=database
Then run these commands

php artisan cache:table
php artisan migrate
Enter fullscreen mode Exit fullscreen mode

step six

Add these lines in top of the app/Providers/AppServiceProvider.php

use App\Repositories\Post\PostCachedRepository;
use App\Repositories\Post\PostRepositoryInterface;
Enter fullscreen mode Exit fullscreen mode

And then add this line in register method

$this->app->bind(PostRepositoryInterface::class, PostCachedRepository::class);

Enter fullscreen mode Exit fullscreen mode

Done :)

Alt Text

Feel free to ask any questions

Top comments (2)

Collapse
 
stnc profile image
Selman TUNÇ

nice tutorials thx , I will implement this in golang

Collapse
 
azibom profile image
Mohammad Reza

You're welcome