如何使用apicache包清除MERN应用中指定路由的缓存?
apicache清除指定路由缓存失效的解决办法
核心问题
apicache默认的缓存键是请求方法+路由路径的组合(比如GET-/api/users/checkJWT),直接传入路径/api/users/checkJWT调用apicache.clear()会匹配不到对应的缓存项,导致清除失败。另外原代码中checkJWT接口的缓存是全局共享的,不同用户的请求会共用同一份缓存,这本身就不合理。
推荐解决方案:按用户维度生成独立缓存键
给每个用户的checkJWT请求生成唯一缓存键,清除时精准定位到当前用户的缓存:
const apicache = require("apicache"); // 初始化apicache实例,方便后续操作 const cache = apicache.options({}).middleware; // 为checkJWT接口生成基于用户ID的缓存键 app.get("/api/users/checkJWT", cache("2 minutes", (req) => { const token = req.headers.authorization?.split(" ")[1]; const decoded = jwt.verify(token, SECRET_KEY); // 用用户ID作为缓存键的一部分,确保每个用户缓存独立 return `checkJWT-${decoded.id}`; }), async (req, res) => { const token = req.headers.authorization?.split(" ")[1]; const decoded = jwt.verify(token, SECRET_KEY); // 只查询一次用户,避免重复数据库请求 const user = await User.findById(decoded.id); if (decoded && user) { return res.status(200).json({ valid: true, user }); } return res.status(400).json({ valid: false }); }); app.patch("/api/users/user", authenticateJWTUser, async (req, res) => { // 清除当前用户的checkJWT缓存 apicache.clear(`checkJWT-${req.user.id}`); const user = await User.findOne({ name: req.body.username }); if (req.body.name != null) user.name = req.body.name; if (req.body.email != null) user.email = req.body.email; if (req.body.password != null) user.password = await bcrypt.hash(req.body.password, 10); if (req.body.tasks != null) user.tasks = req.body.tasks; try { const updatedUser = await user.save(); res.json(updatedUser); } catch (error) { res.status(400).json({ message: error.message }); } });
快速临时修复:匹配默认缓存键
如果不想重构缓存键逻辑,直接用默认的请求方法+路径格式清除:
// 在patch接口里替换原clear语句 apicache.clear('GET-/api/users/checkJWT');
注意:这种方式会清除所有用户的checkJWT缓存,仅适合测试或无用户隔离需求的场景。
额外优化提示
- 原
checkJWT接口重复调用User.findById(decoded.id),改成一次查询复用结果,减少数据库压力。 - 确保
authenticateJWTUser中间件已将用户ID挂载到req.user.id,否则需要调整获取用户ID的方式。
内容的提问来源于stack exchange,提问作者Jesse
相关产品推荐
相关产品推荐

