Caching in laravel with repository and proxy design patterns
Tags: php, laravel, designpatterns, caching
Published: 2020-06-10 11:23:40

## 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
<?php

use Illuminate\Support\Facades\Route;

Route::get('/', 'PostController@index');
``` 

#### step two
Define your controller
```php
<?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();
    }
}

```
#### step three
Make Repository directory in you app directory and fill it like this
```
└── Post
    ├── PostCachedRepository.php
    ├── PostRepositoryInterface.php
    └── PostRepository.php
```
PostCachedRepository.php
```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;
    }
}

```
PostRepositoryInterface.php
```php
<?php

namespace App\Repositories\Post;

interface PostRepositoryInterface {
    public function getTopTen();
}
```

PostRepository.php
```php
<?php

namespace App\Repositories\Post;

use App\Post;

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

```

#### step four
your post model and migration file
app/Post.php
```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model {}

```
And migration file
```php
<?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');
    }
}

```

#### 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
```
#### step six
Add these lines in top of the app/Providers/AppServiceProvider.php
```php
use App\Repositories\Post\PostCachedRepository;
use App\Repositories\Post\PostRepositoryInterface;
```
And then add this line in register method
```php
$this->app->bind(PostRepositoryInterface::class, PostCachedRepository::class);

```

#### Done :)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/co12r7p8dnd963fybh7x.png)

## Feel free to ask any questions