DEV Community

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

Posted on • Edited on

11 2

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

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

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

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay