在Express框架的Node.js项目里,apicache-plus是常用的接口缓存中间件,默认配置下它会按照请求路径生成缓存键,缓存失效时通常会清除所有相关缓存,这种方式在复杂业务场景中会造成不必要的缓存重建开销,因此需要实现精细化的缓存失效控制。

apicache-plus基础使用
首先需要在项目中安装apicache-plus依赖,之后进行基础初始化和中间件挂载,默认配置下缓存会按照完整请求路径作为键存储。
// 安装依赖后引入模块
const apicache = require('apicache-plus');
const express = require('express');
const app = express();
// 初始化缓存实例,设置默认缓存时长10秒
let cache = apicache.middleware('10 seconds');
// 挂载全局缓存中间件,所有路由默认启用缓存
app.use(cache);
// 定义测试路由
app.get('/api/user/:id', (req, res) => {
// 模拟接口处理逻辑,返回用户数据
res.json({
userId: req.params.id,
name: `用户${req.params.id}`,
updateTime: new Date().toISOString()
});
});
app.listen(3000, () => {
console.log('服务启动在3000端口');
});
自定义缓存键实现精细化区分
默认的缓存键仅包含请求路径,无法区分不同请求参数或者用户身份,我们可以通过apicache-plus的配置自定义缓存键生成规则,为后续精细化失效做准备。
缓存键生成配置
apicache-plus支持通过appendKey参数自定义缓存键的拼接内容,我们可以把请求参数、用户信息等内容加入缓存键中。
const apicache = require('apicache-plus');
const express = require('express');
const app = express();
// 自定义缓存键生成函数,拼接请求路径、查询参数、用户id
const customKeyGenerator = (req, res) => {
const basePath = req.path;
const queryStr = JSON.stringify(req.query);
// 假设从请求头获取用户身份标识
const userId = req.headers['x-user-id'] || 'anonymous';
return `${basePath}_${queryStr}_${userId}`;
};
// 初始化缓存中间件,传入自定义键生成函数和缓存时长
let cache = apicache.middleware('10 seconds', customKeyGenerator);
// 仅给指定路由挂载缓存中间件
app.get('/api/article/list', cache, (req, res) => {
// 模拟分页查询文章列表的接口逻辑
const { page = 1, pageSize = 10 } = req.query;
res.json({
page: Number(page),
pageSize: Number(pageSize),
list: [
{ id: 1, title: '测试文章1' },
{ id: 2, title: '测试文章2' }
],
queryTime: new Date().toISOString()
});
});
app.listen(3000, () => {
console.log('服务启动在3000端口');
});
手动失效指定路由缓存
apicache-plus提供了缓存实例的清除方法,我们可以根据自定义的缓存键规则,手动清除指定条件的缓存,实现单条数据的缓存失效。
清除单个缓存键
如果知道具体的缓存键内容,可以直接调用apicache.clear方法清除对应缓存。
const apicache = require('apicache-plus');
const express = require('express');
const app = express();
let cache = apicache.middleware('10 seconds');
// 获取缓存实例的底层存储对象,用于后续操作
const cacheInstance = apicache.getCache();
// 文章更新接口,更新后清除对应文章的详情缓存
app.post('/api/article/update', (req, res) => {
const { articleId } = req.body;
// 模拟文章更新逻辑
// 这里构造之前定义的缓存键,假设用户为匿名,无查询参数
const targetCacheKey = `/api/article/detail_${JSON.stringify({})}_anonymous`;
// 清除指定缓存键
apicache.clear(targetCacheKey);
res.json({ code: 0, msg: '文章更新成功,对应缓存已清除' });
});
// 文章详情路由,使用缓存
app.get('/api/article/detail', cache, (req, res) => {
const { id } = req.query;
res.json({
id,
title: `文章${id}`,
content: '文章内容示例',
queryTime: new Date().toISOString()
});
});
app.listen(3000, () => {
console.log('服务启动在3000端口');
});
批量清除符合规则的缓存
如果需要清除某一类路由的所有缓存,比如清除所有文章相关的缓存,可以通过遍历缓存键的方式批量清除。
const apicache = require('apicache-plus');
const express = require('express');
const app = express();
let cache = apicache.middleware('10 seconds');
const cacheInstance = apicache.getCache();
// 定时任务接口,每小时清除所有文章列表相关的缓存
app.get('/api/clear-article-cache', (req, res) => {
// 获取所有缓存键
const allKeys = Object.keys(cacheInstance._cache || {});
// 筛选包含文章列表路径的缓存键
const articleListKeys = allKeys.filter(key => key.includes('/api/article/list'));
// 批量清除符合条件的缓存
articleListKeys.forEach(key => {
apicache.clear(key);
});
res.json({ code: 0, msg: `成功清除${articleListKeys.length}条文章列表缓存` });
});
app.listen(3000, () => {
console.log('服务启动在3000端口');
});
缓存失效控制最佳实践
在实际项目中,我们可以结合业务场景设计缓存失效策略:
- 对于用户个人数据相关的接口,将用户身份标识加入缓存键,用户数据更新时仅清除该用户对应的缓存
- 对于分类数据接口,将分类ID加入缓存键,分类下内容更新时仅清除对应分类的缓存
- 对于时效性要求高的接口,设置较短的默认缓存时长,同时提供手动失效的接口供业务触发
- 避免在缓存键中加入过多变动频繁的字段,防止缓存命中率过低
通过上述方式,我们可以充分发挥apicache-plus的缓存能力,同时避免默认失效策略带来的性能浪费,实现路由缓存的精细化控制。
apicache-plus路由缓存缓存失效Node.jsExpress修改时间:2026-06-28 06:54:35