-
Notifications
You must be signed in to change notification settings - Fork 518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs(cache): improve documentation and cachedFunction
default options
#1011
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,225 @@ | ||
# Cache API | ||
|
||
Nitro provides a powerful caching system built on top of the storage layer. | ||
Nitro provides a powerful caching system built on top of the [storage layer](/guide/introduction/storage). | ||
|
||
## Usage | ||
It stores the data in the `cache` mountpoint. | ||
- In development, it will use the [FS driver](https://unstorage.unjs.io/drivers/fs) writting to `.nitro/cache` or `.nuxt/cache` if using [Nuxt](https://nuxt.com). | ||
- In production, it will use the [memory driver](https://unstorage.unjs.io/drivers/memory) by default. | ||
|
||
To overwrite the production storage, set the `cache` mountpoint using the `storage` option: | ||
|
||
::code-group | ||
```ts [nitro.config.ts] | ||
import { defineNitroConfig } from "nitropack"; | ||
|
||
```js | ||
const cachedFn = cachedEventHandler(fn, options); | ||
export default defineNitroConfig({ | ||
storage: { | ||
cache: { | ||
driver: 'redis', | ||
/* redis connector options */ | ||
} | ||
} | ||
}) | ||
``` | ||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
nitro: { | ||
storage: { | ||
cache: { | ||
driver: 'redis', | ||
/* redis connector options */ | ||
} | ||
} | ||
} | ||
}) | ||
``` | ||
:: | ||
|
||
### Options | ||
To overwrite the `cache` mountpoint in development, use the `devStorage` option to add the `cache` mountpoint. | ||
|
||
- `name`: Handler name. It will be guessed from function name if not provided and fallback to `_` otherwise. | ||
- `group`: Part of cache name. Useful to organize cache storage. | ||
- `getKey`: A function that accepts same arguments of normal function and should generate cache key. If not provided, a built-in hash function will be used. | ||
- `integrity`: A value that changing it, will invalidate all caches for function. By default will be computed from **function code**. | ||
- `maxAge`: Maximum age that cache is valid in seconds. Default is `1` second. | ||
- `staleMaxAge`: 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 updating the cache in the background. | ||
- `swr`: Enable Stale-While-Revalidate behavior. Enabled by default. | ||
- `base`: Name of the storage mointpoint to use for caching (`/cache` by default) | ||
- `shouldInvalidateCache`: A function that returns a boolean to invalidate the current cache and create a new one. | ||
- `shouldBypassCache`: A function that returns a boolean to bypass the current cache without invalidating the existing entry. | ||
## Usage | ||
|
||
::code-group | ||
```ts [Router Handler] | ||
// Cache an API handler | ||
export default cachedEventHandler((event) => { | ||
// My event handler | ||
}, options); | ||
``` | ||
```ts [Function] | ||
const myFn = cachedFunction(() => { | ||
// My function | ||
}, options); | ||
``` | ||
:: | ||
|
||
## Examples | ||
|
||
**Example:** Cache an API handler | ||
If you come from [Nuxt](https://nuxt.com), all the examples below should be placed inside the `server/` directory. | ||
|
||
```js | ||
// routes/cached.ts | ||
const myFn = cachedEventHandler( | ||
async () => { | ||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
return `Response generated at ${new Date().toISOString()}`; | ||
}, | ||
{ | ||
swr: true, | ||
} | ||
); | ||
### Route Handler | ||
|
||
Cache a route with [stale-while-revalidate](https://www.rfc-editor.org/rfc/rfc5861#section-3) behavior for 10 second: | ||
|
||
```ts [routes/cached.ts] | ||
export default cachedEventHandler(async () => { | ||
return `Response generated at ${new Date().toISOString()}`; | ||
}, { | ||
swr: true, maxAge: 10 | ||
}); | ||
``` | ||
|
||
**Example:** Cache a utility function | ||
The response will be cached for 10 second and a stale value will be sent to the client while the cache is being updated in the background. | ||
|
||
```js | ||
// utils/index.ts | ||
const myFn = cachedFunction( | ||
async () => { | ||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
return Math.random(); | ||
}, | ||
{ | ||
swr: true, | ||
} | ||
); | ||
The cached answer will be store in development inside `.nitro/cache/handlers/_/*.json`. | ||
|
||
### Function | ||
|
||
Cache for 1 hour the result of a function fetching the GitHub stars for a repository: | ||
|
||
::code-group | ||
```ts [utils/github.ts] | ||
export const cachedGHStars = cachedFunction(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 | ||
}) | ||
``` | ||
```ts [api/stars/[...repo].ts] | ||
export default eventHandler(async (event) => { | ||
const repo = event.context.params.repo | ||
const stars = await cachedGHStars(repo).catch(() => 0) | ||
|
||
**Example:** Enable Cache on a group of routes (**π§ͺ Experimental!**) | ||
return { repo, stars } | ||
}) | ||
``` | ||
:: | ||
|
||
The stars will be cached in development inside `.nitro/cache/functions/ghStars/<owner>/<repo>.json` with `value` being the number of stars. | ||
|
||
```json | ||
{"expires":1677851092249,"value":43991,"mtime":1677847492540,"integrity":"ZUHcsxCWEH"} | ||
``` | ||
|
||
```js | ||
// nitro.config.ts | ||
|
||
## Route Rules | ||
|
||
This feature enable to add caching routes based on a glob pattern directly in the main configuration file. | ||
|
||
|
||
::alert{type="primary"} | ||
This features is still experimental and may evolve in the future. | ||
:: | ||
|
||
Cache all the blog routes for 1 hour with `stale-while-revalidate` behavior: | ||
|
||
::code-group | ||
```ts [nitro.config.ts] | ||
import { defineNitroConfig } from "nitropack"; | ||
|
||
export default defineNitroConfig({ | ||
routeRules: { | ||
"/blog/**": { | ||
swr: true, | ||
swr: 60 * 60, | ||
// or | ||
cache: { | ||
maxAge: 60 * 60 | ||
} | ||
}, | ||
}, | ||
}); | ||
``` | ||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
routeRules: { | ||
"/blog/**": { | ||
swr: 60 * 60, | ||
// or | ||
cache: { | ||
maxAge: 60 * 60 | ||
} | ||
}, | ||
} | ||
}); | ||
``` | ||
:: | ||
|
||
**Example:** Set cache storage mountpoint for a group of routes (**π§ͺ Experimental!**) | ||
If we want to use a custom storage mountpoint, we can use the `base` option. Let's store our cache result for the blog routes in a Redis storage for production: | ||
|
||
```js | ||
// nitro.config.ts | ||
::code-group | ||
```ts [nitro.config.ts] | ||
import { defineNitroConfig } from "nitropack"; | ||
|
||
export default defineNitroConfig({ | ||
storage: { | ||
"my-custom-storage": { | ||
redis: { | ||
driver: "redis", | ||
url: "redis://localhost:6379", | ||
}, | ||
}, | ||
routeRules: { | ||
"/blog/**": { | ||
swr: true, | ||
swr: 60 * 60, | ||
cache: { | ||
base: "/my-custom-storage", | ||
base: "redis", | ||
}, | ||
}, | ||
}, | ||
}); | ||
``` | ||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
nitro: { | ||
storage: { | ||
redis: { | ||
driver: "redis", | ||
url: "redis://localhost:6379", | ||
}, | ||
}, | ||
}, | ||
routeRules: { | ||
"/blog/**": { | ||
swr: 60 * 60, | ||
cache: { | ||
base: "redis", | ||
}, | ||
}, | ||
}, | ||
}); | ||
``` | ||
:: | ||
|
||
|
||
## Options | ||
|
||
The `cachedEventHandler` and `cachedFunction` functions accept the following options: | ||
- `name`: Handler name. | ||
- Type: `String` | ||
- Default: guessed from function name if not provided and fallback to `_` otherwise. | ||
- `group`: Part of cache name. Useful to organize cache storage. | ||
- Type: `String` | ||
- Default: `'nitro/handlers'` for handlers and `'nitro/functions'` for functions. | ||
- `getKey`: A function that accepts the same arguments of the function and returns a cache key (`String`). | ||
- Type: `Function` | ||
- Default: If not provided, a built-in hash function will be used. | ||
- `integrity`: A value that invalidates the cache when changed. | ||
- Type: `String` | ||
- Default: computed from **function code**, used in development to invalidate the cache when the function code changes. | ||
- `maxAge`: Maximum age that cache is valid in seconds. | ||
- Type: `Number` | ||
- Default: `1` (second). | ||
- `staleMaxAge`: 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 updating the cache in the background. | ||
- Type: `Number` | ||
- Default: `0` (disabled). | ||
- `swr`: Enable `stale-while-revalidate` behavior. | ||
- Default: `true` | ||
- `base`: Name of the storage mointpoint to use for caching. | ||
- Default: `cache`. | ||
- `shouldInvalidateCache`: A function that returns a `Boolean` to invalidate the current cache and create a new one. | ||
- Type: `Function` | ||
- `shouldBypassCache`: A function that returns a boolean to bypass the current cache without invalidating the existing entry. | ||
- Type: `Function` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is breaking change as invalidates all current prod deployment namespaces π