Nuxtjs如何使用redis

420 阅读3分钟

最近工作在用以nuxtjs框架为基础开发的Vue-storefront。 所以以下代码是以vue-storefront框架为基础的。

当前前端项目是服务器端渲染和浏览器端渲染相结合的,由于原生vue-storefront其实是支持使用redis实现页面缓存的。所以如果想要看页面缓存这块,建议去看官方资料。

而下面是目前项目上需要针对接口缓存的代码。

思路:当前项目在服务器端渲染时候,会获取页面的一些内容的请求,比如storeConfig(店铺信息),currency(货币信息),这些信息是比较稳定的、不大会发生变更的。针对这些接口,可以进行缓存,而与用户个人信息相关的请求,则不建议缓存。因此,在写这块的时候,是针对接口的白名单来设置缓存。

场景:vue-storefront项目,请求流程: 浏览器-> vue项目 -> 后端接口 如:前台网站域名是www.abc.com, 发起storeConfig请求(www.abc.com/magento/sto…

目前是要在上述场景中引入redis —— 请求发起前,判断redis缓存是否存在。如果存在,返回缓存,如果不存在,发起请求,将响应存入缓存,返回响应。

具体代码如下: middleware.config.js

const Redis = require("ioredis");

var redis = new Redis({ 
    port: 6379, 
    host: '127.0.0.1',
    db: 05
  }); // 初始化redis

let redisCacheApi = ['storeConfig', 'currency']; // 需要有缓存的接口名单
let defaultTimeout = 86400; // 之后给缓存设置有效期用,我直接统一一个值,如果不同接口需要不同值,那就专门去设置吧

module.exports = {
  integrations: { // 用于设置集成
    magento: {
      location: '@vue-storefront/magento-api/server',
      extensions:(extensions) => {
        return [
          ...extensions,
          {
            name: 'test',
            extendApiMethods: customMethod,
            extendApp: ({app}) => {
            
              app.use('/:integrationName/:functionName', async (req, res, next) => { // 在中间件中,针对接口白名单里的接口,进行缓存查询
                let cacheKey = req.baseUrl.replace('/magento/', ''); // 这里替换 是因为请求的接口一般是/magento/storeConfig这种格式,不希望在列白名单的时候都有magento这个前缀,所以就在这边进行替换
                let isApiUseRedis = redisCacheApi.includes(cacheKey); // 如果这个请求是在我的白名单里的,去走redis缓存路线,不然就常规的发起请求吧
                if (isApiUseRedis) { // 走redis缓存路线
                  let reqCookies = req.cookies;
                  let storeTag = reqCookies['vsf-store'] || 'default'; // 由于这个项目是有多店铺多货币模式,所以不同的店铺或者货币可能拿取不同的数据,所以缓存的维度上增加的店铺和货币
                  let currencyTag = reqCookies['vsf-currency'] || 'USD';
                  let redisKey = `${keyPrefix}:data:api:${cacheKey}:${storeTag}:${currencyTag}`;
                
                  let cacheValue = await redis.get(`${redisKey}`); // 读取redis中存储的值
                  if (cacheValue) {
                    res.send(JSON.parse(cacheValue)); // 返回缓存
                    return;
                  }
                  next();
                } else {
                  next();
                }
              });              
              
            },
            hooks: (req, res) => {
              let reqCookies = req.cookies;
              let reqBody = req.body;
              let storeTag = reqCookies['vsf-store'] || 'default';
              let currencyTag = reqCookies['vsf-currency'] || 'USD';

              function getRandomInt(max) {
                return Math.floor(Math.random() * max);
              }

              return {
                beforeCreate: ({ configuration }) => configuration,
                afterCreate: ({ configuration }) => configuration,
                beforeCall: ({ configuration, callName, args }) => args,
                afterCall: ({ configuration, callName, args, response }) => { //如果接口没有缓存,就在响应之后,进行缓存
                  let cacheKey = callName.replace('/magento/', '');
                  let isApiUseRedis = redisCacheApi.includes(cacheKey);

                  if (isApiUseRedis) {
                    let redisKey = `${keyPrefix}:data:api:${cacheKey}:${storeTag}`;
                    let expiresTime = parseInt(defaultTimeout) + getRandomInt(120);
                    redis.set(`${redisKey}`, JSON.stringify(response), 'EX', expiresTime); // 存储缓存
                  }
                  
                  return response;
                }
              }
            }
          }
        ]
      },
    },
    // 增加自定义查询
    // customQueries,
  },
};

如果是常规的nuxtjs,不需要这样写,只需要在接口处、或者接口发起前(中间件等位置),判断当前接口是否存在缓存,如果有缓存,读取缓存,没缓存,发起接口,拿取响应,设置缓存,返回响应即可。 以上代码,更适配vue-storefront项目。