DEV Community

loading...
Cover image for Caching in laravel with repository and proxy design patterns

Caching in laravel with repository and proxy design patterns

azibom profile image Mohammad Reza ・2 min read

What is the story

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

so what can you do ?

you can calculate it every hour and save it and then serve it to the user without need to have calculation in your database

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

Discussion (0)

pic
Editor guide