Appearance
hono-cache
简介
hono-cache 是 Hono 框架的缓存中间件,它提供了简单而强大的方式来缓存 API 响应,减少重复计算和数据库查询,提高应用性能。该中间件支持多种缓存策略和存储选项。
安装
bash
npm install hono @hono/cache基本使用
typescript
import { Hono } from 'hono'
import { cache } from '@hono/cache'
const app = new Hono()
// 使用默认配置的缓存中间件
app.get(
'/api/products',
cache({
cacheName: 'api-cache', // 缓存名称
cacheControl: 'max-age=60', // 缓存控制,60秒
}),
async (c) => {
// 这个处理函数只有在缓存未命中时才会执行
console.log('缓存未命中,获取产品数据...')
// 模拟数据库查询
const products = await fetchProductsFromDatabase()
return c.json(products)
},
)
app.listen(3000)
// 模拟数据库查询函数
async function fetchProductsFromDatabase() {
// 在实际应用中,这里会是数据库查询
return [
{ id: 1, name: '产品 A', price: 99.99 },
{ id: 2, name: '产品 B', price: 149.99 },
{ id: 3, name: '产品 C', price: 199.99 },
]
}高级配置
typescript
import { Hono } from 'hono'
import { cache } from '@hono/cache'
const app = new Hono()
// 自定义缓存配置
app.get(
'/api/users/:id',
cache({
// 缓存名称
cacheName: 'users-cache',
// 缓存控制
cacheControl: 'max-age=300, s-maxage=600', // 浏览器缓存5分钟,CDN缓存10分钟
// 缓存键生成函数
cacheKey: (c) => {
// 使用路径和用户ID作为缓存键
const id = c.req.param('id')
return `user-${id}-${c.req.query('version') || 'latest'}`
},
// 是否等待缓存写入完成
wait: true,
// 缓存条件函数
shouldCache: (c) => {
// 只缓存成功的响应
return c.res.status === 200
},
// 缓存过期时间(毫秒)
ttl: 60 * 1000, // 1分钟
// 缓存变体
vary: ['Accept-Language', 'Accept-Encoding'],
}),
async (c) => {
const id = c.req.param('id')
const user = await fetchUserById(id)
if (!user) {
return c.json({ error: '用户不存在' }, 404)
}
return c.json(user)
},
)
// 使用不同配置的缓存中间件
app.get(
'/api/products/:category',
cache({
cacheName: 'products-cache',
// 使用 stale-while-revalidate 策略
cacheControl: 'max-age=60, stale-while-revalidate=600',
// 根据类别和查询参数生成缓存键
cacheKey: (c) => {
const category = c.req.param('category')
const query = new URLSearchParams(c.req.query())
return `products-${category}-${query.toString()}`
},
}),
async (c) => {
const category = c.req.param('category')
const page = parseInt(c.req.query('page') || '1')
const limit = parseInt(c.req.query('limit') || '10')
const products = await fetchProductsByCategory(category, page, limit)
return c.json({
category,
page,
limit,
products,
})
},
)
app.listen(3000)
// 模拟数据获取函数
async function fetchUserById(id: string) {
// 模拟数据库查询延迟
await new Promise((resolve) => setTimeout(resolve, 100))
// 模拟用户数据
const users = {
'1': { id: 1, name: '张三', email: 'zhangsan@example.com' },
'2': { id: 2, name: '李四', email: 'lisi@example.com' },
}
return users[id] || null
}
async function fetchProductsByCategory(category: string, page: number, limit: number) {
// 模拟数据库查询延迟
await new Promise((resolve) => setTimeout(resolve, 200))
// 模拟产品数据
const allProducts = {
electronics: [
{ id: 1, name: '智能手机', price: 3999 },
{ id: 2, name: '笔记本电脑', price: 5999 },
{ id: 3, name: '平板电脑', price: 2999 },
],
clothing: [
{ id: 4, name: 'T恤', price: 99 },
{ id: 5, name: '牛仔裤', price: 199 },
{ id: 6, name: '外套', price: 299 },
],
}
const products = allProducts[category] || []
const start = (page - 1) * limit
const end = start + limit
return products.slice(start, end)
}与内存缓存集成
typescript
import { Hono } from 'hono'
import { cache } from '@hono/cache'
const app = new Hono()
// 创建内存缓存存储
const memoryStore = new Map()
app.get(
'/api/stats',
cache({
cacheName: 'stats-cache',
cacheControl: 'max-age=60',
// 使用自定义存储
storage: {
async get(key: string) {
const cached = memoryStore.get(key)
if (!cached) return null
const { value, expires } = cached
if (expires < Date.now()) {
memoryStore.delete(key)
return null
}
return value
},
async set(key: string, value: any, ttl: number) {
const expires = Date.now() + ttl
memoryStore.set(key, { value, expires })
},
async delete(key: string) {
memoryStore.delete(key)
},
},
}),
async (c) => {
// 模拟获取统计数据(耗时操作)
const stats = await generateStats()
return c.json(stats)
},
)
app.listen(3000)
// 模拟统计数据生成
async function generateStats() {
// 模拟耗时计算
await new Promise((resolve) => setTimeout(resolve, 500))
return {
totalUsers: 10000,
activeUsers: 5000,
totalProducts: 1000,
timestamp: new Date().toISOString(),
}
}