zoukankan      html  css  js  c++  java
  • 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 IlluminateFoundationHttpEventsRequestHandled;
    *
    *
    *
    protected $listen = [
        RequestHandled::class => [
            AppListenersCacheApiResult::class
        ]
    ];

    然后在项目的根目录执行 php artisan event:generate 这个命令用来生成event文件和listener文件;event用的是框架自带的RequestHandled事件,所以不会有改动,这个命令只会在app/Listeners文件夹下添加一个CacheApiResult.php文件。 文件内容如下

     
    <?php
    namespace AppListeners;
    use Cache;
    use IlluminateFoundationHttpEventsRequestHandled;
    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 AppHttpMiddleware;
    use Closure;
    use Cache;
    class ApiCache
    {
        /**
         * Handle an incoming request.
         *
         * @param  IlluminateHttpRequest  $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' => AppHttpMiddlewareApiCache::class,

     
    protected $routeMiddleware = [
            'auth' => AppHttpMiddlewareAuthenticate::class,
            'auth.basic' => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class,
            'bindings' => IlluminateRoutingMiddlewareSubstituteBindings::class,
            'cache.headers' => IlluminateHttpMiddlewareSetCacheHeaders::class,
            'can' => IlluminateAuthMiddlewareAuthorize::class,
            'guest' => AppHttpMiddlewareRedirectIfAuthenticated::class,
            'change' => AppHttpMiddlewareChangeJsonToForm::class,
            'signed' => IlluminateRoutingMiddlewareValidateSignature::class,
            'throttle' => IlluminateRoutingMiddlewareThrottleRequests::class,
            'verified' => IlluminateAuthMiddlewareEnsureEmailIsVerified::class,
            'apiCache' => AppHttpMiddlewareApiCache::class,
        ];

    这样就完成了这个缓存系统。其中的缓存我用的是redis,这个可以按需配置,不了解可以看一下lavarel的缓存知识。

    这只是一个初级版,以后有需要可以升级一下。

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

  • 相关阅读:
    mysql week 的使用方法
    获取某个周在本年的开始日期和结束日期
    question and answer
    系统安装
    adblock 下载地址
    windows新增/修改/删除系统环境变量bat示例,一键配置JAVA_HOME
    SpringMVC 复杂对象数据绑定
    IntelliJ IDEA default settings 全局默认设置
    Spring整合Ehcache管理缓存
    label的for属性
  • 原文地址:https://www.cnblogs.com/aipiaoborensheng/p/12787850.html
Copyright © 2011-2022 走看看