-
-
Notifications
You must be signed in to change notification settings - Fork 87
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
feat: @adonisjs/cache docs #157
Draft
Julien-R44
wants to merge
3
commits into
main
Choose a base branch
from
feat/cache-docs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+266
−0
Draft
Changes from all commits
Commits
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
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 |
---|---|---|
@@ -0,0 +1,198 @@ | ||
--- | ||
summary: Cache data to improve the performance of your application | ||
--- | ||
|
||
# Cache | ||
|
||
AdonisJS Cache (`@adonisjs/cache`) is a simple, lightweight wrapper built on top of [bentocache.dev](https://bentocache.dev) to cache data and enhance the performance of your application. It provides a straightforward and unified API to interact with various cache drivers, such as Redis, DynamoDB, PostgreSQL, in-memory caching, and more. | ||
|
||
We highly encourage you to read the Bentocache documentation. Bentocache offers some advanced, optional concepts that can be very useful in certain situations, such as [multi-tiering](https://bentocache.dev/docs/multi-tier), [grace periods](https://bentocache.dev/docs/grace-periods), [timeouts](https://bentocache.dev/docs/timeouts), and more. | ||
|
||
## Installation | ||
|
||
Install and configure the `@adonisjs/cache` package by running the following command: | ||
|
||
```sh | ||
node ace add @adonisjs/cache | ||
``` | ||
|
||
:::disclosure{title="See the steps performed by the add command"} | ||
|
||
1. Installs the `@adonisjs/cache` package using the detected package manager. | ||
2. Registers the following service provider inside the `adonisrc.ts` file: | ||
|
||
```ts | ||
{ | ||
providers: [ | ||
// ...other providers | ||
() => import('@adonisjs/cache/cache_provider'), | ||
] | ||
} | ||
``` | ||
|
||
3. Creates the `config/cache.ts` file. | ||
4. Defines the environment variables for the selected cache drivers inside the `.env` file. | ||
|
||
::: | ||
|
||
## Configuration | ||
|
||
The configuration file for the cache package is located at `config/cache.ts`. You can configure the default cache driver, the list of drivers, and their specific configurations. | ||
|
||
See also: [Config stub](https://github.com/adonisjs/cache/blob/1.x/stubs/config.stub) | ||
|
||
```ts | ||
import { defineConfig, store, drivers } from '@adonisjs/cache' | ||
|
||
const cacheConfig = defineConfig({ | ||
default: 'redis', | ||
suppressL2Errors: false, | ||
gracePeriod: { | ||
enabled: true, | ||
duration: '60s', | ||
}, | ||
stores: { | ||
/** | ||
* Cache data only on DynamoDB | ||
*/ | ||
dynamodb: store().useL2Layer(drivers.dynamodb({})), | ||
|
||
/** | ||
* Cache data using your Lucid-configured database | ||
*/ | ||
database: store().useL2Layer(drivers.database({ connectionName: 'default' })), | ||
|
||
/** | ||
* Cache data in-memory as the primary store and Redis as the secondary store. | ||
* If your application is running on multiple servers, then in-memory caches | ||
* need to be synchronized using a bus. | ||
*/ | ||
redis: store() | ||
.useL1Layer(drivers.memory({ maxSize: 10 * 1024 * 1024 })) | ||
.useL2Layer(drivers.redis({ connectionName: 'main' })) | ||
.useBus(drivers.redisBus({ connectionName: 'main' })), | ||
}, | ||
}) | ||
|
||
export default cacheConfig | ||
``` | ||
|
||
In the code example above, we are setting up multiple layers for each cache store. This is called a [multi-tier caching system](https://bentocache.dev/docs/multi-tier). It lets us first check a fast in-memory cache (the first layer). If we do not find the data there, we will then use the distributed cache (the second layer). | ||
|
||
### Redis | ||
|
||
To use Redis as your cache system, you must install the `@adonisjs/redis` package and configure it. Refer to the documentation here: [Redis](../database/redis.md). | ||
|
||
In `config/cache.ts`, you must specify a `connectionName`. This property should match the Redis configuration key in the `config/redis.ts` file. | ||
|
||
### Database | ||
|
||
The `database` driver has a peer dependency on `@adonisjs/lucid`. Therefore, you must install and configure this package to use the `database` driver. | ||
|
||
In `config/cache.ts`, you must specify a `connectionName`. This property should correspond to the database configuration key in the `config/database.ts` file. | ||
|
||
### Other drivers | ||
|
||
You can use other drivers such as `memory`, `dynamodb`, `kysely` and `orchid`. | ||
|
||
See [Cache Drivers](https://bentocache.dev/docs/cache-drivers) for more information. | ||
|
||
## Usage | ||
|
||
Once your cache is configured, you can import the `cache` service to interact with it. In the following example, we cache the user details for 5 minutes: | ||
|
||
```ts | ||
import cache from '@adonisjs/cache/services/main' | ||
import router from '@adonisjs/core/services/router' | ||
|
||
router.get('/user/:id', async ({ params }) => { | ||
return cache.getOrSet({ | ||
key: `user:${params.id}`, | ||
duration: '5m', | ||
factory: async () => { | ||
const user = await User.find(params.id) | ||
return user.toJSON() | ||
}, | ||
}) | ||
}) | ||
``` | ||
|
||
Key points to note here: | ||
|
||
- We are using the [`getOrSet`](https://bentocache.dev/docs/methods#getorset) method. The first time the route is accessed, it will fetch the user details from the database and cache them for 5 minutes. Subsequent requests will return the cached value. | ||
- The `factory` method is a callback that executes when the cache key is missing. The return value of the factory method is then cached. | ||
- As you can see, we serialize the user's data using `user.toJSON()`. This is necessary because your data must be serialized to be stored in the cache. Classes such as Lucid models or instances of `Date` cannot be stored directly in caches like Redis or a database. | ||
|
||
## Cache Service | ||
|
||
The cache service exported from `@adonisjs/cache/services/main` is a singleton instance of the [BentoCache](https://bentocache.dev/docs/named-caches) class created using the configuration defined in `config/cache.ts`. | ||
|
||
You can import the cache service into your application and use it to interact with the cache: | ||
|
||
```ts | ||
import cache from '@adonisjs/cache/services/main' | ||
|
||
/** | ||
* Without calling the `use` method, the methods you call on the cache service | ||
* will use the default store defined in `config/cache.ts`. | ||
*/ | ||
cache.put({ key: 'username', value: 'jul', ttl: '1h' }) | ||
|
||
/** | ||
* Using the `use` method, you can switch to a different store defined in | ||
* `config/cache.ts`. | ||
*/ | ||
cache.use('dynamodb').put({ key: 'username', value: 'jul', ttl: '1h' }) | ||
``` | ||
|
||
You can find all available methods here: [BentoCache API](https://bentocache.dev/docs/methods). | ||
|
||
```ts | ||
await cache.namespace('users').set({ key: 'username', value: 'jul' }) | ||
await cache.namespace('users').get('username') | ||
|
||
await cache.get('username') | ||
|
||
await cache.set('username', 'jul') | ||
await cache.setForever('username', 'jul') | ||
|
||
await cache.getOrSet({ | ||
key: 'username', | ||
ttl: '1h', | ||
factory: async () => fetchUserName(), | ||
}) | ||
|
||
await cache.has('username') | ||
await cache.missing('username') | ||
|
||
await cache.pull('username') | ||
|
||
await cache.delete('username') | ||
await cache.deleteMany(['products', 'users']) | ||
|
||
await cache.clear() | ||
``` | ||
|
||
## Edge Helper | ||
|
||
The `cache` service is available as an edge helper within your views. You can use it to retrieve cached values directly in your templates. | ||
|
||
```edge | ||
<p> | ||
Hello {{ await cache.get('username') }} | ||
</p> | ||
``` | ||
|
||
## Ace Commands | ||
|
||
The `@adonisjs/cache` package also provides a set of Ace commands to interact with the cache from the terminal. | ||
|
||
### cache:clear | ||
|
||
Clears the cache for the specified store. If not specified, it will clear the default one. | ||
|
||
```sh | ||
node ace cache:clear | ||
node ace cache:clear redis | ||
node ace cache:clear dynamodb | ||
``` |
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.
The
Digging Deeper
section is alphabetically sorted. So we should move up this sub-section.