天气API应用缓存位置咨询:Axios层还是Express层?
缓存层级选择:Axios层 vs Express层
针对你的天气应用,两种层级加缓存各有优劣,具体选哪个取决于你的业务场景:
在Axios层(forecast函数内)添加缓存
优势
- 缓存逻辑和第三方API调用绑定,不管Express路由如何调整,或是后续其他模块调用该forecast函数,都能自动复用缓存,复用性强。
- 直接减少对OpenWeatherMap API的请求次数,节省API调用配额,降低触发限流的风险。
劣势
- 缓存标识仅能基于
location参数生成,无法结合HTTP请求的其他扩展参数(比如后续新增的温度单位、语言偏好等)实现精细化缓存。 - 缓存是全局统一的,无法针对不同Express路由设置差异化的过期时间或失效策略。
在Express层(/weather路由内)添加缓存
优势
- 可以基于完整的请求参数组合(比如
locale加上其他query参数)生成缓存键,缓存策略更灵活。 - 可直接在响应中设置
Cache-Control这类HTTP缓存头,让客户端浏览器也能缓存响应结果,进一步降低服务器压力。 - 能为该特定路由定制缓存规则,比如针对不同地区设置不同的缓存过期时间。
劣势
- 缓存逻辑与路由绑定,后续新增其他调用forecast函数的路由时,需要重复编写缓存逻辑。
- 只有通过该路由的请求能享受缓存,其他直接调用forecast的场景无法复用缓存。
推荐方案
- 如果你的应用仅有这一个路由调用forecast,或是需要针对HTTP请求做灵活的缓存控制(比如客户端缓存),优先选择Express层。
- 如果forecast函数会被多个模块调用,想要统一缓存逻辑、最大化减少第三方API请求,优先选择Axios层。
- 也可以结合两者:Axios层做底层API请求缓存,Express层再做HTTP层面的缓存增强,双重提升性能。
代码示例
Express层加缓存(使用memory-cache)
const cache = require('memory-cache'); app.get('/weather', (req, res) => { const locale = req.query.locale; if(!locale) { return res.send({ error: 'Please provide valid locale' }) } const cacheKey = `weather_${locale}`; const cachedData = cache.get(cacheKey); if (cachedData) { console.log('返回缓存的天气数据', cachedData); return res.send({ weatherData: cachedData }); } foreCast(locale, (err, weatherData) => { if(err) { console.log('调用天气API出错') res.send({err}); } else { // 设置缓存10分钟过期 cache.put(cacheKey, weatherData, 10 * 60 * 1000); console.log('返回最新天气数据', weatherData) res.send({weatherData}) } }); })
Axios层加缓存(使用memory-cache)
import { weatherApiKey } from 'config'; import axios from 'axios'; const cache = require('memory-cache'); const forecast = (location, service) => { const cacheKey = `weather_api_${location}`; const cachedData = cache.get(cacheKey); if (cachedData) { console.log('使用缓存数据,地点: ', location); return service(undefined, cachedData); } console.log('调用API获取数据,地点: ', location); axios.get(`http://api.openweathermap.org/data/2.5/weather?q=${location}&appid=${weatherApiKey}`) .then(res => { // 设置缓存10分钟过期 cache.put(cacheKey, res.data, 10 * 60 * 1000); service(undefined, res.data) }) .catch(err => { service('Error calling weather API'); }) } module.exports = forecast;
内容的提问来源于stack exchange,提问作者hulike2286
相关产品推荐
相关产品推荐

