缓存
¥Cache
Nitro 提供了一个基于存储层构建的缓存系统。
缓存事件处理程序
¥Cached event handlers
要缓存事件处理程序,只需使用 defineCachedEventHandler
方法即可。
¥To cache an event handler, you simply need to use the defineCachedEventHandler
method.
它的工作原理与 defineEventHandler
类似,但多了一个 options 参数。
¥It works like defineEventHandler
but with an additional second options parameter.
// Cache an API handler
export default defineCachedEventHandler((event) => {
// My event handler
}, { maxAge: 60 * 60 /* 1 hour */ });
在此示例中,响应将被缓存 1 小时,并且在后台更新缓存时,将向客户端发送一个过时的值。如果你想立即返回更新后的响应集 swr: false
。
¥With this example, the response will be cached for 1 hour and a stale value will be sent to the client while the cache is being updated in the background. If you want to immediately return the updated response set swr: false
.
::important 处理缓存响应时,所有传入的请求标头都将被丢弃。如果你定义了 varies
选项,则在缓存和提供响应时只会考虑指定的标头。::
¥::important
All incoming request headers are dropped when handling cached responses. If you define the varies
option, only the specified headers will be considered when caching and serving the responses.
::
有关可用选项的更多详细信息,请参阅 options 部分。
¥See the options section for more details about the available options.
cachedEventHandler
方法用作 defineCachedEventHandler
的别名。缓存函数
¥Cached functions
你还可以使用 defineCachedFunction
函数缓存函数。这对于缓存不是事件处理程序但属于事件处理程序一部分的函数的结果并在多个处理程序中重用它非常有用。
¥You can also cache a function using the defineCachedFunction
function. This is useful for caching the result of a function that is not an event handler, but is part of one, and reusing it in multiple handlers.
例如,你可能希望将 API 调用的结果缓存一小时:
¥For example, you might want to cache the result of an API call for one hour:
export const cachedGHStars = defineCachedFunction(async (repo: string) => {
const data: any = await $fetch(`https://api.github.com/repos/${repo}`)
return data.stargazers_count
}, {
maxAge: 60 * 60,
name: 'ghStars',
getKey: (repo: string) => repo
})
星星将在开发环境中缓存在 .nitro/cache/functions/ghStars/<owner>/<repo>.json
中,value
表示星星数量。
¥The stars will be cached in development inside .nitro/cache/functions/ghStars/<owner>/<repo>.json
with value
being the number of stars.
{"expires":1677851092249,"value":43991,"mtime":1677847492540,"integrity":"ZUHcsxCWEH"}
::important 由于缓存数据被序列化为 JSON,因此缓存函数不能返回任何无法序列化的内容,例如符号、映射、集合……::
¥::important Because the cached data is serialized to JSON, it is important that the cached function does not return anything that cannot be serialized, such as Symbols, Maps, Sets… ::
cachedFunction
方法用作 defineCachedFunction
的别名。Edge Workers
在边缘工作器中,实例会在每次请求后销毁。Nitro 自动使用 event.waitUntil
保持实例活动,同时缓存更新,并将响应发送到客户端。
¥In edge workers, the instance is destroyed after each request. Nitro automatically uses event.waitUntil
to keep the instance alive while the cache is being updated while the response is sent to the client.
为确保你的缓存函数在边缘工作器中按预期工作,你应始终将 event
作为第一个参数传递给使用 defineCachedFunction
的函数。
¥To ensure that your cached functions work as expected in edge workers, you should always pass the event
as the first argument to the function using defineCachedFunction
.
import type { H3Event } from 'h3'
export const cachedGHStars = defineCachedFunction(async (event: H3Event, repo: string) => {
const data: any = await $fetch(`https://api.github.com/repos/${repo}`)
return data.stargazers_count
}, {
maxAge: 60 * 60,
name: 'ghStars',
getKey: (event: H3Event, repo: string) => repo
})
这样,该函数将能够在更新缓存时保持实例活动,而不会降低对客户端的响应速度。
¥This way, the function will be able to keep the instance alive while the cache is being updated without slowing down the response to the client.
缓存路由规则
¥Caching route rules
此功能允许你直接在主配置文件中基于 glob 模式添加缓存路由。这对于为应用的某个部分设置全局缓存策略尤其有用。
¥This feature enables you to add caching routes based on a glob pattern directly in the main configuration file. This is especially useful to have a global cache strategy for a part of your application.
使用 stale-while-revalidate
行为缓存所有博客路由 1 小时:
¥Cache all the blog routes for 1 hour with stale-while-revalidate
behavior:
export default defineNitroConfig({
routeRules: {
"/blog/**": { cache: { maxAge: 60 * 60 } },
},
});
如果我们想使用 自定义存储 挂载点,我们可以使用 base
选项。
¥If we want to use a custom storage mount point, we can use the base
option.
export default defineNitroConfig({
storage: {
redis: {
driver: "redis",
url: "redis://localhost:6379",
},
},
routeRules: {
"/blog/**": { cache: { maxAge: 60 * 60, base: "redis" } },
},
});
自定义缓存存储
¥Customize cache storage
Nitro 将数据存储在 cache:
挂载点。
¥Nitro stores the data in the cache:
mount point.
要覆盖生产存储,请使用 storage
选项设置 cache
挂载点:
¥To overwrite the production storage, set the cache
mount point using the storage
option:
export default defineNitroConfig({
storage: {
cache: {
driver: 'redis',
/* redis connector options */
}
}
})
在开发模式下,你还可以使用 devStorage
选项覆盖缓存挂载点:
¥In development, you can also overwrite the cache mount point using the devStorage
option:
export default defineNitroConfig({
devStorage: {
cache: {
driver: 'redis',
/* redis connector options */
}
}
})
选项
¥Options
cachedEventHandler
和 cachedFunction
函数接受以下选项:
¥The cachedEventHandler
and cachedFunction
functions accept the following options:
::field-group ::field{name="base" type="string"} 用于缓存的存储挂载点的名称。:br 默认为 cache
。:: ::field{name="name" type="string"} 如果未提供,则根据函数名称进行猜测,否则回退到 '_'
。:: ::field{name="group" type="string"} 默认为 'nitro/handlers'
(处理程序)和 'nitro/functions'
(函数)。:: ::field{name="getKey()" type="(...args) => string"} 函数,接受与原始函数相同的参数并返回缓存键 (String
)。:br 如果未提供,则将使用内置哈希函数根据函数参数生成密钥。:: ::field{name="integrity" type="string"} 一个值,更改后缓存将失效。::warning 🚧 WinterJS 运行时默认情况下,它是根据函数代码计算的,在开发中用于在函数代码更改时使缓存失效。:: ::field{name="maxAge" type="number"} 缓存的最长有效期(以秒为单位)。:br 默认为 1
(秒)。:: ::field{name="staleMaxAge" type="number"} 过时缓存的最长有效期(以秒为单位)。如果设置为 -1
,则在缓存在后台更新时,仍会向客户端发送过时的值。:br 默认为 0
(禁用)。:: ::field{name="swr" type="boolean"} 启用 stale-while-revalidate
行为,在异步重新验证缓存响应的同时提供过时的缓存响应。:br 默认为 true
。:: ::field{name="shouldInvalidateCache()" type="(..args) => boolean"} 函数,返回 boolean
值以使当前缓存失效并创建新缓存。:: ::field{name="shouldBypassCache()" type="(..args) => boolean"} 函数,返回 boolean
值以绕过当前缓存,而不会使现有条目失效。:: ::field{name="varies" type="string"} 一个请求标头数组,用于缓存 了解更多。如果在多租户环境中使用,你可能需要传递 ['host', 'x-forwarded-host']
以确保这些标头不会被丢弃,并且每个租户的缓存都是唯一的。:: ::
¥::field-group
Name of the storage mountpoint to use for caching.
Default to cache
.
Guessed from function name if not provided, and falls back to '_'
otherwise.
Defaults to 'nitro/handlers'
for handlers and 'nitro/functions'
for functions.
A function that accepts the same arguments as the original function and returns a cache key (String
).
If not provided, a built-in hash function will be used to generate a key based on the function arguments.
A value that invalidates the cache when changed.
By default, it is computed from function code, used in development to invalidate the cache when the function code changes.
Maximum age that cache is valid, in seconds.
Default to 1
(second).
Maximum age that a stale cache is valid, in seconds. If set to -1
a stale value will still be sent to the client while the cache updates in the background.
Defaults to 0
(disabled).
Enable stale-while-revalidate
behavior to serve a stale cached response while asynchronously revalidating it.
Defaults to true
.
A function that returns a boolean
to invalidate the current cache and create a new one.
A function that returns a boolean
to bypass the current cache without invalidating the existing entry.
An array of request headers to be considered for the cache, learn more. If utilizing in a multi-tenant environment, you may want to pass ['host', 'x-forwarded-host']
to ensure these headers are not discarded and that the cache is unique per tenant.
::
缓存键和失效
¥Cache keys and invalidation
使用 defineCachedFunction
或 defineCachedEventHandler
函数时,缓存键将使用以下模式生成:
¥When using the defineCachedFunction
or defineCachedEventHandler
functions, the cache key is generated using the following pattern:
`${options.group}:${options.name}:${options.getKey(...args)}.json`
例如,以下函数:
¥For example, the following function:
const getAccessToken = defineCachedFunction(() => {
return String(Date.now())
}, {
maxAge: 10,
name: 'getAccessToken',
getKey: () => 'default'
})
将生成以下缓存键:
¥Will generate the following cache key:
nitro:functions:getAccessToken:default.json
你可以使用以下方法使缓存的函数条目无效:
¥You can invalidate the cached function entry with:
await useStorage('cache').removeItem('nitro:functions:getAccessToken:default.json')