laravel添加api緩存系統


項目背景:最初是想給接口加緩存,但是不想每個接口添加緩存代碼,就寫了個統一的緩存系統。

技術方案:

  1. 本項目使用laravel框架
  2. 監聽requestHanled事件寫入緩存
  3. 添加apiCache中間件,對每個get訪問進行攔截,檢查是否有緩存,如果有,就讀取緩存就返回,如果沒有,就執行下一個中間件。

前置知識:

  1. laravel框架基礎知識
  2. event(事件)和listener(監聽器);
  3. middleware(中間件)
  4. cache

下面是代碼實現:

1,首先在app/Providers/EventServiceProvider.php 里添加對應的event和listener。

 
use Illuminate\Foundation\Http\Events\RequestHandled;
*
*
*
protected $listen = [
    RequestHandled::class => [
        \App\Listeners\CacheApiResult::class
    ]
];

然后在項目的根目錄執行 php artisan event:generate 這個命令用來生成event文件和listener文件;event用的是框架自帶的RequestHandled事件,所以不會有改動,這個命令只會在app/Listeners文件夾下添加一個CacheApiResult.php文件。 文件內容如下

 
<?php
namespace App\Listeners;
use Cache;
use Illuminate\Foundation\Http\Events\RequestHandled;
class CacheApiResult
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }
    /**
     * Handle the event.
     *
     * @param  RequestHandled  $event
     * @return void
     */
    public function handle(RequestHandled $event)
    {
        //$event->response->isCached這個屬性是在后面的中間件里面加的,對象本身是沒有這個屬性的。
        if($event->request->isMethod('GET') && !isset($event->response->isCached) ){
            //這里的key生成規則是我自己定義的,可以按需更改。
            $uri = $event->request->getUri();
            $params = $event->request->all();
            $keyStr = $uri.'::';
            foreach($params as $key => $val){
                $keyStr = $keyStr.$key.':'.$val.'::';
            }
            $key = md5($keyStr);
            $data = $event->response->getContent();
            Cache::set($key, $data, 1);
            //這里緩存一分鍾,目前看來分鍾好像是最小粒度了,以后需要再改進;可以按需改成其他緩存
            }
    }
}

然后需要添加一個中間件 添加app/Http/Middleware/ApiCache.php文件

 
<?php
namespace App\Http\Middleware;
use Closure;
use Cache;
class ApiCache
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if($request->isMethod('GET')){
            $uri = $request->getUri();
            $params = $request->all();
            $keyStr = $uri.'::';
            foreach($params as $key => $val){
                $keyStr = $keyStr.$key.':'.$val.'::';
            }
            $key = md5($keyStr);
            $data = Cache::get($key);
            if($data){
                $data = json_decode($data,true);
                $response = response()->json($data);
                $response->isCached = true;//添加這個屬性是為了避免監聽器重復寫入緩存
                return $response;
            }
        }
        return $next($request);
    }
}

然后要去注冊這個中間件,讓每個請求都經過它。

在app/Http/Kernel.php文件的$routeMiddleware中添加一個元素 'apiCache' => \App\Http\Middleware\ApiCache::class,

 
protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'change' => \App\Http\Middleware\ChangeJsonToForm::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'apiCache' => \App\Http\Middleware\ApiCache::class,
    ];

這樣就完成了這個緩存系統。其中的緩存我用的是redis,這個可以按需配置,不了解可以看一下lavarel的緩存知識。

這只是一個初級版,以后有需要可以升級一下。

原創地址:https://blog.csdn.net/u010965027/article/details/87934651


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM