最近工作在用以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项目。