缓存
缓存处理器
要缓存事件处理器,你只需要使用 defineCachedHandler 方法。
它的工作方式类似于 defineHandler,但有一个用于缓存选项的第二个参数。
import { defineCachedHandler } from "nitro/runtime";
export default defineCachedHandler((event) => {
return "我缓存了一小时";
}, { maxAge: 60 * 60 });
在这个例子中,响应将被缓存 1 小时,在后台更新缓存时,会向客户端发送一个陈旧的值。如果你想立即返回更新的响应,设置 swr: false。
有关可用选项的更多详细信息,请参阅选项部分。
varies 选项在缓存和提供响应时考虑特定的头。缓存函数
你也可以使用 defineCachedFunction 函数缓存一个函数。这对于缓存不是事件处理器但是其中一个部分的函数的结果,并在多个处理器中重用很有用。
例如,你可能想要缓存 API 调用的结果一小时:
import { defineHandler, defineCachedFunction } from "nitro/runtime";
export default defineHandler(async (event) => {
const { repo } = event.context.params;
const stars = await cachedGHStars(repo).catch(() => 0)
return { repo, stars }
});
const cachedGHStars = defineCachedFunction(async (repo: string) => {
const data = await fetch(`https://api.github.com/repos/${repo}`).then(res => res.json());
return data.stargazers_count;
}, {
maxAge: 60 * 60,
name: "ghStars",
getKey: (repo: string) => repo
});
在开发中,stars 将被缓存在 .nitro/cache/functions/ghStars/<owner>/<repo>.json 中,value 是 star 的数量。
{"expires":1677851092249,"value":43991,"mtime":1677847492540,"integrity":"ZUHcsxCWEH"}
在 edge workers 中,实例在每次请求后都会被销毁。Nitro 自动使用 event.waitUntil 在响应发送给客户端时保持实例存活,同时更新缓存。
为了确保你的缓存函数在 edge workers 中按预期工作,你应该始终将 event 作为第一个参数传递给使用 defineCachedFunction 的函数。
import { defineHandler, defineCachedFunction, type H3Event } from "nitro/runtime";
export default defineHandler(async (event) => {
const { repo } = event.context.params;
const stars = await cachedGHStars(event, repo).catch(() => 0)
return { repo, stars }
});
const cachedGHStars = defineCachedFunction(async (event: H3Event, repo: string) => {
const data = await fetch(`https://api.github.com/repos/${repo}`).then(res => res.json());
return data.stargazers_count;
}, {
maxAge: 60 * 60,
name: "ghStars",
getKey: (event: H3Event, repo: string) => repo
});
这样,函数将能够在缓存更新时保持实例存活,而不会减慢对客户端的响应。
使用路由规则
此功能使你能够直接在主配置文件中基于 glob 模式添加缓存路由。这对于为应用程序的某部分设置全局缓存策略特别有用。
使用 stale-while-revalidate 行为缓存所有博客路由一小时:
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
routeRules: {
"/blog/**": { cache: { maxAge: 60 * 60 } },
},
});
如果我们想使用自定义缓存存储挂载点,我们可以使用 base 选项。
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
storage: {
redis: {
driver: "redis",
url: "redis://localhost:6379",
},
},
routeRules: {
"/blog/**": { cache: { maxAge: 60 * 60, base: "redis" } },
},
});
缓存存储
Nitro 将数据存储在 cache 存储挂载点中。
要覆盖生产存储,使用 storage 选项设置 cache 挂载点:
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
storage: {
cache: {
driver: 'redis',
/* redis 连接器选项 */
}
}
})
在开发中,你也可以使用 devStorage 选项覆盖缓存挂载点:
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
storage: {
cache: {
// 生产缓存存储
},
},
devStorage: {
cache: {
// 开发缓存存储
}
}
})
选项
defineCachedHandler 和 defineCachedFunction 函数接受以下选项:
cache。'_'。'nitro/handlers',函数默认为 'nitro/functions'。String)的函数。:br
如果未提供,将使用内置哈希函数基于函数参数生成键。1(秒)。-1,在后台更新缓存时仍会向客户端发送陈旧的值。:br
默认为 0(禁用)。stale-while-revalidate 行为,在异步重新验证时提供陈旧的缓存响应。:br
默认为 true。boolean 的函数,用于使当前缓存失效并创建新缓存。boolean 的函数,用于绕过当前缓存而不使现有条目失效。['host', 'x-forwarded-host'] 以确保这些头不被丢弃,并且缓存对每个租户是唯一的。缓存键和失效
使用 defineCachedFunction 或 defineCachedHandler 函数时,缓存键使用以下模式生成:
`${options.group}:${options.name}:${options.getKey(...args)}.json`
例如,以下函数:
import { defineCachedFunction } from "nitro/runtime";
const getAccessToken = defineCachedFunction(() => {
return String(Date.now())
}, {
maxAge: 10,
name: "getAccessToken",
getKey: () => "default"
});
将生成以下缓存键:
nitro:functions:getAccessToken:default.json
你可以使用以下方式使缓存函数条目失效:
import { useStorage } from "nitro/runtime";
await useStorage('cache').removeItem('nitro:functions:getAccessToken:default.json')