docs: Caching Module (#13701)
* standard docs for caching module + deprecated cache module * added guides for creating + using, and overall changes from cache to caching * fix details related to redis provider * fix build errors * fix build error * fixes * add guides to sidebar * add sidebar util * document query + index * moved cache tag conventions * fix build errors * added migration guide * added memcached guide * fixes * general fixes and updates * updated reference * document medusa cache * small fix * fixes * remove cloud cache * revert edit dates changes * revert edit dates * small update
This commit is contained in:
@@ -14,6 +14,14 @@ export const metadata = {
|
||||
|
||||
In this guide, you’ll learn how to create a Cache Module.
|
||||
|
||||
{/* TODO add link */}
|
||||
|
||||
<Note title="Deprecation Notice">
|
||||
|
||||
The Cache Module is deprecated starting from [Medusa v2.11.0](https://github.com/medusajs/medusa/releases/tag/v2.11.0). [Create a Caching Module Provider](#) instead.
|
||||
|
||||
</Note>
|
||||
|
||||
## 1. Create Module Directory
|
||||
|
||||
Start by creating a new directory for your module. For example, `src/modules/my-cache`.
|
||||
|
||||
@@ -12,6 +12,12 @@ This module is helpful for development or when you’re testing out Medusa, but
|
||||
|
||||
For production, it’s recommended to use modules like [Redis Cache Module](../redis/page.mdx).
|
||||
|
||||
<Note title="Deprecation Notice">
|
||||
|
||||
The In-Memory Cache Module is deprecated starting from [Medusa v2.11.0](https://github.com/medusajs/medusa/releases/tag/v2.11.0). Use the [Caching Module](../../caching/page.mdx) instead.
|
||||
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## Register the In-Memory Cache Module
|
||||
|
||||
@@ -8,6 +8,12 @@ export const metadata = {
|
||||
|
||||
In this document, you'll learn what a Cache Module is and how to use it in your Medusa application.
|
||||
|
||||
<Note title="Deprecation Notice">
|
||||
|
||||
The Cache Module is deprecated starting from [Medusa v2.11.0](https://github.com/medusajs/medusa/releases/tag/v2.11.0). Use the [Caching Module](../caching/page.mdx) instead.
|
||||
|
||||
</Note>
|
||||
|
||||
## What is a Cache Module?
|
||||
|
||||
A Cache Module is used to cache the results of computations such as price selection or various tax calculations.
|
||||
|
||||
@@ -8,9 +8,9 @@ export const metadata = {
|
||||
|
||||
The Redis Cache Module uses Redis to cache data in your store. In production, it's recommended to use this module.
|
||||
|
||||
<Note title="Using Cloud?">
|
||||
<Note title="Deprecation Notice">
|
||||
|
||||
Our Cloud offering automatically provisions a Redis instance and configures the Redis Cache Module for you. Learn more in the [Redis](!cloud!/redis) Cloud documentation.
|
||||
The Redis Cache Module is deprecated starting from [Medusa v2.11.0](https://github.com/medusajs/medusa/releases/tag/v2.11.0). Use the [Redis Caching Module Provider](../../caching/providers/redis/page.mdx) instead.
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -32,10 +32,6 @@ export const highlights = [
|
||||
]
|
||||
|
||||
```ts title="medusa-config.ts" highlights={highlights}
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
|
||||
// ...
|
||||
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
export const metadata = {
|
||||
title: `Caching Module Concepts`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this guide, you'll learn about the main concepts of the [Caching Module](../page.mdx), including cache keys, cache tags, and automatic cache invalidation.
|
||||
|
||||
## Cache Keys
|
||||
|
||||
Cache keys uniquely identify cached data in the caching service. The Caching Module automatically generates cache keys when you cache data with Query or the Index Module.
|
||||
|
||||
### Custom Cache Keys
|
||||
|
||||
When you cache custom data with the Caching Module's service, you can generate a cache key using the [computeKey](/references/caching-service#computeKey) method. This method generates a unique key based on the data you want to cache.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const data = { id: "prod_123", title: "Product 123" }
|
||||
const key = await cachingModuleService.computeKey(data)
|
||||
await cachingModuleService.set({
|
||||
key,
|
||||
tags: ["Product:prod_123", "Product:list:*"],
|
||||
data
|
||||
})
|
||||
```
|
||||
|
||||
The `computeKey` method takes an object as input and generates a unique key based on its properties.
|
||||
|
||||
The generated key is a hash string that uniquely identifies the data. The has doesn't change based on the order of properties in the object.
|
||||
|
||||
For example, the following two objects generate the same cache key:
|
||||
|
||||
```ts
|
||||
const key1 = await cachingModuleService.computeKey({ id: "prod_123", title: "Product 123" })
|
||||
const key2 = await cachingModuleService.computeKey({ title: "Product 123", id: "prod_123" })
|
||||
|
||||
console.log(key1 === key2) // true
|
||||
```
|
||||
|
||||
### When to Use Custom Cache Keys?
|
||||
|
||||
Use custom cache keys when you're caching custom data with the Caching Module's service. This ensures that the cached data is uniquely identified and can be retrieved or invalidated correctly.
|
||||
|
||||
You can also pass a custom key to Query or the Index Module when caching data. This is useful when you want to use the key for custom invalidation or retrieval.
|
||||
|
||||
Learn more about passing custom keys in the [Query guide](!docs!/learn/fundamentals/module-links/query#set-cache-key).
|
||||
|
||||
---
|
||||
|
||||
## Cache Tags
|
||||
|
||||
Cache tags are useful for grouping cached data, making it easier to invalidate or retrieve related cached entries.
|
||||
|
||||
When you cache data with the Query or Index Module, the Caching Module automatically generates cache tags based on the entity being queried and its retrieved relations.
|
||||
|
||||
When you cache custom data with the Caching Module's service, you can pass custom tags to the `set` and `get` methods.
|
||||
|
||||
### Caching Tags Convention
|
||||
|
||||
The Caching Module generates cache tags in the following format:
|
||||
|
||||
- `Entity:id`: Cache tag for a single record of an entity. For example, `Product:prod_123` for caching a single product with the ID `prod_123`.
|
||||
- `Entity:list:*`: Cache tag for a list of records of an entity. For example, `Product:list:*` for caching a list of products.
|
||||
|
||||
<Note>
|
||||
|
||||
`Entity` is the pascal-cased name of the data model, which you pass as the first parameter to `model.define` when defining the model.
|
||||
|
||||
</Note>
|
||||
|
||||
When you use custom tags, ensure they adhere to the above convention. Otherwise, the Caching Module cannot automatically invalidate your cached data. You'll have to [invalidate](/references/caching-service#clear) the cached data manually.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
const key = await cachingModuleService.computeKey(data)
|
||||
await cachingModuleService.set({
|
||||
key,
|
||||
tags: ["Product:list:*", "Product:prod_123"],
|
||||
data
|
||||
})
|
||||
```
|
||||
|
||||
### When to Use Custom Tags?
|
||||
|
||||
Use custom tags when you want to group cached data for custom invalidation or retrieval.
|
||||
|
||||
Note that if your custom tags do not follow the [Caching Tags Convention](#caching-tags-convention), the Caching Module cannot automatically invalidate your cached data. You must manually [invalidate](/references/caching-service#clear) the cached data when it changes.
|
||||
|
||||
---
|
||||
|
||||
## Automatic Cache Invalidation
|
||||
|
||||
### When is Cache Automatically Invalidated?
|
||||
|
||||
The Caching Module automatically invalidates cached data when the underlying data changes through database operations such as create, update, or delete.
|
||||
|
||||
For example, if you cache a list of products with the tag `Product:list:*` and a new product is created, the Caching Module automatically invalidates the cached list of products.
|
||||
|
||||
This ensures that your application always serves fresh data and avoids serving stale or outdated information.
|
||||
|
||||
The following table shows when the Caching Module invalidates cached data based on different database operations:
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>
|
||||
Database Operation
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell>
|
||||
Invalidated Cache Tags
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
Create
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
`Entity:list:*` (`Product:list:*`)
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
Update
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
`Entity:{id}`, `Entity:list:*` if the list includes the updated record. (`Product:prod_123`, `Product:list:*`)
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
Delete
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
`Entity:list:*` (`Product:list:*`)
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
### Which Data is Automatically Invalidated?
|
||||
|
||||
The Caching Module automatically invalidates your cached data when:
|
||||
|
||||
1. The data includes an `id` field. This is used internally to map the data to the corresponding cache tags.
|
||||
- When retrieving data with Query or the Index Module, ensure the `id` field is included in the `fields` option.
|
||||
|
||||
```ts
|
||||
const { data: products } = useQueryGraphStep({
|
||||
entity: "product",
|
||||
fields: ["id", "title"], // Ensure 'id' is included, or pass '*'
|
||||
options: {
|
||||
cache: {
|
||||
enable: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
- When caching custom data with the Caching Module's service, ensure the data object includes an `id` property.
|
||||
2. Custom tags follow the [Caching Tags Convention](#caching-tags-convention).
|
||||
|
||||
```ts
|
||||
const data = { id: "prod_123", title: "Product 123" }
|
||||
const key = await cachingModuleService.computeKey(data)
|
||||
await cachingModuleService.set({
|
||||
key,
|
||||
tags: ["Product:prod_123", "Product:list:*"],
|
||||
data
|
||||
})
|
||||
```
|
||||
|
||||
3. The `autoInvalidate` option is not set or is set to `true`. This option is enabled by default.
|
||||
|
||||
```ts
|
||||
const { data: products } = useQueryGraphStep({
|
||||
entity: "product",
|
||||
fields: ["id", "title"],
|
||||
options: {
|
||||
cache: {
|
||||
enable: true,
|
||||
// This is enabled by default
|
||||
// autoInvalidate: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Invalidation of Related Entities
|
||||
|
||||
If the cached data includes relations, and the relation is updated, the Caching Module also invalidates the cache tags for the related entity.
|
||||
|
||||
For example, consider the following Query usage:
|
||||
|
||||
```ts
|
||||
const { data: products } = useQueryGraphStep({
|
||||
entity: "product",
|
||||
fields: ["id", "title", "variants.*"],
|
||||
options: {
|
||||
cache: {
|
||||
enable: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
If the product's variant is updated, the Caching Module invalidates the cache tags for both the `Product` and `ProductVariant` entities.
|
||||
|
||||
### When to Disable Automatic Invalidation?
|
||||
|
||||
Disabling automatic invalidation means the data remains in the cache until it expires (based on the TTL) or is manually invalidated.
|
||||
|
||||
Consider disabling automatic invalidation in the following cases:
|
||||
|
||||
1. You're caching data that rarely changes, such as a list of countries.
|
||||
2. You want to manage cache invalidation manually, such as when caching data as part of a custom workflow where you want to control when the cache is invalidated.
|
||||
3. You're caching data that does not belong to a Medusa data model, such as data from an external API or computed values. This data is not automatically invalidated by default.
|
||||
|
||||
Disable automatic invalidation by setting the `autoInvalidate` option to `false` when caching data with Query, the Index Module, or the Caching Module's service.
|
||||
|
||||
When you disable automatic invalidation, manually [invalidate](/references/caching-service#clear) the cached data when it changes.
|
||||
|
||||
---
|
||||
|
||||
## Caching Best Practices
|
||||
|
||||
### Cache Rarely-Changing Data
|
||||
|
||||
Cache data that is read frequently but changes infrequently, such as product information, categories, or static content.
|
||||
|
||||
Caching such data can significantly improve performance and reduce database load.
|
||||
|
||||
### Do Not Cache Dynamic Data
|
||||
|
||||
Avoid caching data that changes frequently or is user-specific, such as shopping cart contents, user sessions, or product pricing.
|
||||
|
||||
Caching such data can lead to inconsistencies and stale information being served to users. It also increases bandwidth and memory usage, as the cache is updated frequently.
|
||||
|
||||
### Do Not Cache Frequently Updated Data
|
||||
|
||||
Avoid caching data that is updated frequently, such as inventory levels or order statuses.
|
||||
|
||||
Caching such data increases the overhead of cache invalidation and may lead to performance degradation.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
import { Prerequisites } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Migrate from Cache Module to Caching Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this guide, you'll learn how to migrate from the deprecated [Cache Module](../../cache/page.mdx) to the new [Caching Module](../page.mdx).
|
||||
|
||||
<Note>
|
||||
|
||||
The Caching Module is available starting [Medusa v2.11.0](https://github.com/medusajs/medusa/releases/tag/v2.11.0).
|
||||
|
||||
</Note>
|
||||
|
||||
<Note title="This guide is for developers who have">
|
||||
|
||||
1. Set up a Cache Module in `medusa-config.ts`.
|
||||
2. Used the Cache Module's service in their code.
|
||||
|
||||
If you haven't done either of these, you don't need to migrate to the Caching Module. You can refer to the [Caching Module guide](../page.mdx#install-the-caching-module) to learn how to set it up.
|
||||
|
||||
</Note>
|
||||
|
||||
## Why Migrate to the Caching Module?
|
||||
|
||||
The Caching Module provides improved performance, flexibility, and scalability compared to the deprecated Cache Module.
|
||||
|
||||
It also offers a better developer experience, making it easier to cache Query results and other data.
|
||||
|
||||
Additionally, the Caching Module supports registering multiple caching providers, such as Redis and Memcached, allowing you to use different caching backends in your application.
|
||||
|
||||
---
|
||||
|
||||
## Architectural Module Changes
|
||||
|
||||
The Cache Module implements caching logic, including integration with third-party caching services like Redis. For example, the Redis Cache Module handled connecting to the Redis server and performing caching operations.
|
||||
|
||||
The Caching Module, on the other hand, follows a provider-based architecture. The Caching Module provides the interface you use to manage cached data, while Caching Module Providers implement the actual caching logic. You can choose which provider to use, such as the Redis Caching Module Provider or a custom provider you create.
|
||||
|
||||
This separation of concerns allows for greater flexibility and extensibility. You can easily switch between different caching providers or create your own custom provider without modifying the core Caching Module.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## How to Migrate to the Caching Module
|
||||
|
||||
<Prerequisites
|
||||
items={[
|
||||
{
|
||||
text: "Updated your Medusa application to v2.11.0 or later",
|
||||
link: "https://github.com/medusajs/medusa/releases/tag/v2.11.0"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
### 1. Remove the Cache Module
|
||||
|
||||
The first step is to remove the Cache Module from your `medusa-config.ts` file.
|
||||
|
||||
For example, if you set up the Redis Cache Module, remove the following code from `medusa-config.ts`:
|
||||
|
||||
```ts title="medusa-config.ts" highlights={[["5"], ["6"], ["7"], ["8"], ["9"], ["10"]]}
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
// REMOVE THE FOLLOWING LINES
|
||||
{
|
||||
resolve: "@medusajs/medusa/cache-redis",
|
||||
options: {
|
||||
redisUrl: process.env.CACHE_REDIS_URL,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
### 2. Install and Register the Caching Module
|
||||
|
||||
The Caching Module is installed by default in your application. To use it, enable the caching feature flag and register the module in your `medusa-config.ts` file.
|
||||
|
||||
Refer to the [Caching Module guide](../page.mdx#install-the-caching-module) for setup instructions.
|
||||
|
||||
### 3. (Optional) Update Your Code to Use the Caching Module's Service
|
||||
|
||||
If you're using the Cache Module's service in your code, update it to use the Caching Module's service instead.
|
||||
|
||||
#### Container Key Change
|
||||
|
||||
Previously, you resolved the Cache Module's service using the `Modules.CACHE` or `cache` key.
|
||||
|
||||
Now, use the `Modules.CACHING` or `caching` key to resolve the Caching Module's service. For example:
|
||||
|
||||
```ts
|
||||
const cachingModuleService = container.resolve(Modules.CACHING)
|
||||
// or
|
||||
const cachingModuleService = container.resolve("caching")
|
||||
```
|
||||
|
||||
#### Method Changes
|
||||
|
||||
The Caching Module's service has similar methods to the Cache Module's service:
|
||||
|
||||
1. `get` -> Use the Caching Module's [get method](/references/caching-service#get).
|
||||
2. `set` -> Use the Caching Module's [set method](/references/caching-service#set).
|
||||
3. `invalidate` -> Use the Caching Module's [clear method](/references/caching-service#clear).
|
||||
|
||||
### 4. (Optional) Create Custom Caching Module Provider
|
||||
|
||||
If you have a custom Cache Module, recreate it as a custom Caching Module Provider. For example, recreate a custom Memcached Cache Module as a Caching Module Provider.
|
||||
|
||||
The Caching Module Provider's service has similar methods to the Cache Module's service. Refer to the [Create Caching Module Provider guide](/references/caching-module-provider) for instructions on creating a custom Caching Module Provider.
|
||||
|
||||
---
|
||||
|
||||
## Understand Caching Changes
|
||||
|
||||
With the Cache Module, you handled caching and invalidation manually.
|
||||
|
||||
The Caching Module can now handle caching and invalidation automatically for certain operations, such as caching Query results. You can still use the Caching Module's service to cache custom data.
|
||||
|
||||
Learn more about the Caching Module in the [Caching Module guide](../page.mdx).
|
||||
@@ -0,0 +1,318 @@
|
||||
import { CardList, Card, Table, CodeTabs, CodeTab } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Caching Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this guide, you'll learn about the Caching Module and its providers.
|
||||
|
||||
<Note>
|
||||
|
||||
The Caching Module is available starting [Medusa v2.11.0](https://github.com/medusajs/medusa/releases/tag/v2.11.0). It replaces the deprecated [Cache Module](../cache/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
## What is the Caching Module?
|
||||
|
||||
The Caching Module provides functionality to cache data in your Medusa application, improving performance and reducing latency for frequently accessed data.
|
||||
|
||||
For example, Medusa uses the Caching Module to cache product information, and you can cache custom data such as brand information.
|
||||
|
||||
The Caching Module stores and retrieves cached data using the caching service you integrate, such as [Redis](./providers/redis/page.mdx) or [Memcached](./guides/memcached/page.mdx). This provides flexibility in customizing your Medusa application's infrastructure to meet your performance and scalability requirements.
|
||||
|
||||

|
||||
|
||||
### Caching Module vs Cache Module
|
||||
|
||||
Before Medusa v2.11.0, you used the [Cache Module](../cache/page.mdx) to cache data. The Cache Module is now deprecated and has been replaced by the Caching Module.
|
||||
|
||||
If you're using the Cache Module in your application, refer to the [migrate to the Caching Module](./migrate-cache/page.mdx).
|
||||
|
||||
---
|
||||
|
||||
## Install the Caching Module
|
||||
|
||||
The Caching Module is installed by default in your application. To use it, enable the caching feature flag and register the module in your `medusa-config.ts` file.
|
||||
|
||||
{/* <Note title="Cloud user?">
|
||||
|
||||
Caching features are enabled by default for Cloud users. Learn more in the [Medusa Cache](!cloud!/cache) guide.
|
||||
|
||||
</Note> */}
|
||||
|
||||
### 1. Enable Caching Feature Flag
|
||||
|
||||
The caching feature is currently behind a feature flag. To enable it, set the `MEDUSA_FF_CACHING` environment variable to `true` in your `.env` file:
|
||||
|
||||
```bash
|
||||
MEDUSA_FF_CACHING=true
|
||||
```
|
||||
|
||||
This enables you to use the Caching Module and activates caching features in Medusa's core.
|
||||
|
||||
### 2. Register the Caching Module
|
||||
|
||||
Next, add the Caching Module to the `modules` property of the exported object in `medusa-config.ts`:
|
||||
|
||||
```ts title="medusa-config.ts"
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/caching",
|
||||
options: {
|
||||
providers: [
|
||||
{
|
||||
resolve: "@medusajs/caching-redis",
|
||||
id: "caching-redis",
|
||||
// Optional, makes this the default caching provider
|
||||
is_default: true,
|
||||
options: {
|
||||
redisUrl: process.env.CACHE_REDIS_URL,
|
||||
// more options...
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
This registers the Caching Module in your application with the [Redis Caching Module Provider](./providers/redis/page.mdx).
|
||||
|
||||
<Note>
|
||||
|
||||
The Caching Module requires at least one Caching Module Provider to be registered. If you do not register any providers, the Caching Module throws an error when your application starts.
|
||||
|
||||
</Note>
|
||||
|
||||
### What is a Caching Module Provider?
|
||||
|
||||
A Caching Module Provider implements the underlying logic for caching data, such as integrating third-party caching services. The Caching Module then uses the registered Caching Module Provider to handle caching operations.
|
||||
|
||||
Refer to the [Caching Module Providers guide](./providers/page.mdx) to learn more about Caching Module Providers in Medusa, and how to configure the default provider.
|
||||
|
||||
<CardList
|
||||
items={[
|
||||
{
|
||||
title: "Redis",
|
||||
href: "/infrastructure-modules/caching/providers/redis",
|
||||
badge: {
|
||||
variant: "green",
|
||||
children: "For Production"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Memcached",
|
||||
href: "/infrastructure-modules/caching/guides/memcached",
|
||||
badge: {
|
||||
variant: "blue",
|
||||
children: "Tutorial"
|
||||
}
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
### What Data is Cached by Default?
|
||||
|
||||
After you enable the Caching Module, Medusa automatically caches data for several business-critical APIs to boost performance and throughput. This includes all cart-related operations, where the following data is cached:
|
||||
|
||||
- Regions
|
||||
- Promotion codes
|
||||
- Variant price sets
|
||||
- Variants
|
||||
- Shipping options
|
||||
- Sales channels
|
||||
- Customers
|
||||
|
||||
---
|
||||
|
||||
## How to Use the Caching Module
|
||||
|
||||
You can cache data with the Caching Module in two ways: by caching data retrieved with [Query](!docs!/learn/fundamentals/module-links/query) or the [Index Module](!docs!/learn/fundamentals/module-links/index-module), or by directly using the [Caching Module's service](/references/caching-service).
|
||||
|
||||
### 1. Caching with Query or Index Module
|
||||
|
||||
You can cache results from Query and the Index Module by passing the `cache` option to the `query.graph` and `query.index` methods, or to the `useQueryGraphStep` in workflows.
|
||||
|
||||
For example:
|
||||
|
||||
```ts highlights={[["14"], ["15"], ["16"]]}
|
||||
import {
|
||||
createWorkflow,
|
||||
WorkflowResponse
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
|
||||
|
||||
export const workflow = createWorkflow(
|
||||
"workflow-1",
|
||||
() => {
|
||||
const { data: products } = useQueryGraphStep({
|
||||
entity: "product",
|
||||
fields: ["id", "title"],
|
||||
options: {
|
||||
cache: {
|
||||
enable: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return new WorkflowResponse(products)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
The `useQueryGraphStep` accepts an `options.cache` property that enables and configures caching of the results.
|
||||
|
||||
When caching is enabled, the Caching Module stores the results in the underlying caching service (for example, Redis). Subsequent calls to the same query retrieve the results from the cache, improving performance.
|
||||
|
||||
Query and the Index Module accept other caching options. Learn more in the [Query](!docs!/learn/fundamentals/module-links/query#cache-query-results) and [Index Module](!docs!/learn/fundamentals/module-links/index-module#cache-index-module-results) guides.
|
||||
|
||||
### 2. Caching with the Caching Module's Service
|
||||
|
||||
You can also use the Caching Module's service directly to cache custom data in your Medusa application.
|
||||
|
||||
For example, resolve the Caching Module's service in a workflow step and use its methods to cache brand information:
|
||||
|
||||
export const cachingHighlights = [
|
||||
["14", "computeKey", "Compute the cache key."],
|
||||
["15", "get", "Retrieve the cached value for the `brand` tag."],
|
||||
["19", "cachedValue", "If a cached value exists, return it."],
|
||||
["23", "getBrand", "Fetch the brand data if not cached."],
|
||||
["25", "set", "Cache the fetched brand data with the `brand` tag."]
|
||||
]
|
||||
|
||||
```ts highlights={cachingHighlights}
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
type StepInput = {
|
||||
filters: Record<string, unknown>
|
||||
}
|
||||
|
||||
export const getBrandStep = createStep(
|
||||
"get-brand-step",
|
||||
async (input: StepInput, { container }) => {
|
||||
const cachingModuleService = container.resolve(Modules.CACHING)
|
||||
const brandModuleService = container.resolve("brand")
|
||||
|
||||
const cacheKey = await cachingModuleService.computeKey(input.filters)
|
||||
const cachedValue = await cachingModuleService.get({
|
||||
tags: ["brand"]
|
||||
})
|
||||
|
||||
if (cachedValue) {
|
||||
return new StepResponse(cachedValue)
|
||||
}
|
||||
|
||||
const brand = await brandModuleService.getBrand(input.filters)
|
||||
|
||||
await cachingModuleService.set({
|
||||
key: cacheKey,
|
||||
tags: [`Brand:${brand.id}`],
|
||||
data: brand
|
||||
})
|
||||
|
||||
return new StepResponse(brand)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
In the example above, you create a step that resolves the Caching Module's service from the [Medusa container](!docs!/learn/fundamentals/medusa-container).
|
||||
|
||||
Then, you use the `get` method of the service to retrieve a cached value with the tag `"brand"`. You can also use other methods such as `set` to cache a value and `clear` to remove a cached value.
|
||||
|
||||
Learn about other methods and options of the Caching Module in the [Use Caching Module](/references/caching-service) guide.
|
||||
|
||||
### Which Caching Method Should You Use?
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>
|
||||
Caching Method
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell>
|
||||
When to Use
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
Query or Index Module
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Ideal for standard data retrieval scenarios, such as fetching products or custom data.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
Caching Module's Service
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Suitable for caching computed values, external API responses, or to control caching behavior.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
Caching data with Query or the Index Module is ideal when retrieving standard data, such as products or custom entities. The Caching Module automatically handles cache keys and invalidation for you.
|
||||
|
||||
If you need to cache custom data like computed values or external API responses, or you want finer control over caching behavior, use the Caching Module's service directly. In this case, you must manage cache keys yourself, though you can still enable automatic invalidation using the service's `set` method.
|
||||
|
||||
---
|
||||
|
||||
## Caching Module Options
|
||||
|
||||
You can pass the following options to the Caching Module when registering it in your `medusa-config.ts` file:
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>
|
||||
Option
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell>
|
||||
Description
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell>
|
||||
Default
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`ttl`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
A number indicating the default time-to-live (TTL) in seconds for cached items. After this period, cached items will be removed from the cache.
|
||||
This number is passed to the underlying caching provider if no TTL is specified when caching data.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
`3600` (1 hour)
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`providers`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
An array of caching providers to use. This allows you to configure multiple caching providers for different use cases.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
No providers by default
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
---
|
||||
|
||||
## Caching Concepts
|
||||
|
||||
To learn more about caching concepts such as cache keys, cache tags, and automatic cache invalidation, refer to the [Caching Module Concepts guide](./concepts/page.mdx).
|
||||
@@ -0,0 +1,157 @@
|
||||
import { CardList, Card, Table, CodeTabs, CodeTab } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Caching Module Providers`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this guide, you'll learn about Caching Module Providers in Medusa, including how to configure and use them in your Medusa application.
|
||||
|
||||
## What is a Caching Module Provider?
|
||||
|
||||
A Caching Module Provider implements the logic for caching data, such as integrating third-party caching services. The [Caching Module](../page.mdx) then uses the registered Caching Module Providers to handle caching data.
|
||||
|
||||
Medusa provides the [Redis Caching Module Provider](./redis/page.mdx) that you can use in development and production. You can also [Create a Caching Provider](/references/caching-module-provider).
|
||||
|
||||
<CardList
|
||||
items={[
|
||||
{
|
||||
title: "Redis",
|
||||
href: "/infrastructure-modules/caching/providers/redis",
|
||||
badge: {
|
||||
variant: "green",
|
||||
children: "For Production"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Memcached",
|
||||
href: "/infrastructure-modules/caching/guides/memcached",
|
||||
badge: {
|
||||
variant: "blue",
|
||||
children: "Tutorial"
|
||||
}
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
---
|
||||
|
||||
## Default Caching Module Provider
|
||||
|
||||
You can register multiple Caching Module Providers and specify which one to use as the default. The Caching Module uses the default provider for all caching operations unless you specify a specific provider.
|
||||
|
||||
### How is the Default Provider Selected?
|
||||
|
||||
The Caching Module determines the default Caching Module Provider based on the following scenarios:
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Scenario</Table.HeaderCell>
|
||||
<Table.HeaderCell>Default Provider</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
One provider is registered.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The registered provider.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
Multiple providers and one of them has an `is_default` flag.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The provider with the `is_default` flag set to `true`.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
If none of the above scenarios apply, the Caching Module throws an error during startup indicating that no default provider is configured.
|
||||
|
||||
### Setting the Default Caching Module Provider
|
||||
|
||||
To specify a provider as the default, you can set its `is_default` option to `true` when registering it in the `provider` array of the Caching Module.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title="medusa-config.ts"
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/caching",
|
||||
options: {
|
||||
providers: [
|
||||
{
|
||||
id: "caching-redis",
|
||||
resolve: "@medusajs/caching-redis",
|
||||
is_default: true, // Set as the default provider
|
||||
options: {
|
||||
// Redis options...
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "caching-memcached",
|
||||
resolve: "./path/to/your/memcached-provider",
|
||||
options: {
|
||||
// Memcached options...
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
In this example, the Redis Caching Module Provider is set as the default provider by setting `is_default: true`. The Memcached Caching Module Provider is also registered but not set as the default.
|
||||
|
||||
---
|
||||
|
||||
## Caching with Specific Providers
|
||||
|
||||
Whether you're caching data with Query, the Index Module, or directly using the Caching Module's service, you can specify an array of provider IDs to use for that specific caching operation.
|
||||
|
||||
For example, considering you have the [above configuration](../page.mdx#setting-the-default-caching-module-provider) with both Redis and Memcached providers registered, you can specify which provider to use when caching data:
|
||||
|
||||
<CodeTabs group="caching-method">
|
||||
<CodeTab label="Query / Index Module" value="query-index">
|
||||
|
||||
```ts highlights={[["7"]]}
|
||||
const { data: products } = useQueryGraphStep({
|
||||
entity: "product",
|
||||
fields: ["id", "title"],
|
||||
options: {
|
||||
cache: {
|
||||
enable: true,
|
||||
providers: ["caching-memcached"] // Specify Memcached provider
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
<CodeTab label="Caching Module Service" value="caching-service">
|
||||
|
||||
```ts highlights={[["6"]]}
|
||||
const cachingModuleService = container.resolve(Modules.CACHING)
|
||||
|
||||
await cachingModuleService.set({
|
||||
key: "product-list",
|
||||
data: products,
|
||||
providers: ["caching-memcached"] // Specify Memcached provider
|
||||
})
|
||||
```
|
||||
|
||||
</CodeTab>
|
||||
</CodeTabs>
|
||||
|
||||
In this example, both Query and the Caching Module's service use the Memcached provider, overriding the default Redis provider.
|
||||
|
||||
The ID you pass is the same ID you specified in `medusa-config.ts` when registering the provider.
|
||||
@@ -0,0 +1,198 @@
|
||||
import { Table, Prerequisites } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Redis Caching Module Provider`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The Redis Caching Module Provider is a robust caching solution that leverages [Redis](https://redis.io/) to store cached data. Redis offers high performance, scalability, and data persistence, making it an ideal choice for production environments.
|
||||
|
||||
<Note>
|
||||
|
||||
The Caching Module and its providers are available starting [Medusa v2.11.0](https://github.com/medusajs/medusa/releases/tag/v2.11.0).
|
||||
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## Register the Redis Caching Module
|
||||
|
||||
<Prerequisites items={[
|
||||
{
|
||||
text: "Redis installed and Redis server running",
|
||||
link: "https://redis.io/docs/getting-started/installation/"
|
||||
}
|
||||
]} />
|
||||
|
||||
To use the Redis Caching Module Provider, you need to register it in the `providers` array of the Caching Module in your `medusa-config.ts`.
|
||||
|
||||
```ts title="medusa-config.ts"
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/caching",
|
||||
options: {
|
||||
providers: [
|
||||
{
|
||||
resolve: "@medusajs/caching-redis",
|
||||
id: "caching-redis",
|
||||
// Optional, makes this the default caching provider
|
||||
is_default: true,
|
||||
options: {
|
||||
redisUrl: process.env.CACHE_REDIS_URL,
|
||||
// more options...
|
||||
},
|
||||
},
|
||||
// other caching providers...
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
Notice that you pass an `id` property to the provider. The provider will be registered with that ID, which you can use to explicitly [specify the provider when caching data](../page.mdx#how-to-use-the-caching-module).
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Make sure to add the following environment variable:
|
||||
|
||||
```bash
|
||||
CACHE_REDIS_URL=redis://localhost:6379
|
||||
```
|
||||
|
||||
### Redis Caching Module Options
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>
|
||||
Option
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell>
|
||||
Description
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell>
|
||||
Default
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`redisUrl`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
The connection URL for the Redis server.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
Required. An error is thrown if not provided.
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`ttl`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
A number indicating the default time-to-live (TTL) in seconds for cached items. After this period, cached items will be removed from the cache.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
`3600` (1 hour)
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`prefix`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
A string to prefix all cache keys with. This is useful for namespacing your cache keys, especially when sharing a Redis instance with other applications or modules.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
No prefix by default
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
`compressionThreshold`
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
A number indicating the size threshold in bytes above which cached items will be compressed before being stored in Redis. This helps save memory when caching large items.
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
`1024` (1 KB)
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
---
|
||||
|
||||
## Test the Redis Caching Module
|
||||
|
||||
You can test the Redis Caching Module by caching data using the Query or Index Module, or by directly using the Caching Module's service, as described in the [Caching Module guide](../page.mdx#how-to-use-the-caching-module).
|
||||
|
||||
If you don't set the Redis Caching Module Provider as the default, you can explicitly specify its provider ID `caching-redis` when caching data with Query, the Index Module, or directly with the Caching Module's service.
|
||||
|
||||
<Note title="Tip">
|
||||
|
||||
`caching-redis` is the ID you set in the `medusa-config.ts` file when registering the Redis Caching Module Provider.
|
||||
|
||||
</Note>
|
||||
|
||||
For example, you can create a workflow in `src/workflows/cache-products.ts` that caches products using the Redis Caching Module Provider:
|
||||
|
||||
```ts title="src/workflows/cache-products.ts" highlights={[["14"], ["15"], ["16"], ["17"]]}
|
||||
import {
|
||||
createWorkflow,
|
||||
WorkflowResponse
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { useQueryGraphStep } from "@medusajs/medusa/core-flows"
|
||||
|
||||
export const cacheProductsWorkflow = createWorkflow(
|
||||
"cache-products",
|
||||
() => {
|
||||
const { data: products } = useQueryGraphStep({
|
||||
entity: "product",
|
||||
fields: ["id", "title"],
|
||||
options: {
|
||||
cache: {
|
||||
enable: true,
|
||||
providers: ["caching-redis"],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return new WorkflowResponse(products)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
Next, execute that workflow in an [API route](!docs!/learn/fundamentals/api-routes). For example, create a route at `src/api/cache-product/route.ts` with the following content:
|
||||
|
||||
```ts title="src/api/cache-product/route.ts"
|
||||
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
|
||||
import { cacheProductsWorkflow } from "../../workflows/cache-products"
|
||||
|
||||
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||
const { result } = await cacheProductsWorkflow(req.scope)
|
||||
.run({})
|
||||
|
||||
res.status(200).json(result)
|
||||
}
|
||||
```
|
||||
|
||||
Finally, start your Medusa server with the following command:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Then, make a `GET` request to the `/cache-product` endpoint:
|
||||
|
||||
```bash
|
||||
curl http://localhost:9000/cache-product
|
||||
```
|
||||
|
||||
You should receive a response with the list of products. The first time you make this request, the products will be fetched from the database and cached in Redis. Subsequent requests will retrieve the products from the cache, resulting in improved performance.
|
||||
@@ -60,7 +60,7 @@ Then, you use the `retrieveFile` method of the File Module to retrieve the URL o
|
||||
|
||||
---
|
||||
|
||||
### What is a File Module Provider?
|
||||
## What is a File Module Provider?
|
||||
|
||||
A File Module Provider implements the underlying logic of handling uploads and downloads of assets, such as integrating third-party services. The File Module then uses the registered File Module Provider to handle file operations.
|
||||
|
||||
|
||||
@@ -47,29 +47,36 @@ The Analytics Module exposes functionalities to track and analyze user interacti
|
||||
|
||||
|
||||
|
||||
## Cache Module
|
||||
## Caching Module
|
||||
|
||||
A Cache Module is used to cache the results of computations such as price selection or various tax calculations. Learn more in [this documentation](./cache/page.mdx).
|
||||
The Caching Module provides functionality to cache data in your Medusa application, improving performance and reducing latency for frequently accessed data.
|
||||
|
||||
The following Cache modules are provided by Medusa. You can also create your own cache module as explained in [this guide](./cache/create/page.mdx).
|
||||
The following Caching modules are provided by Medusa. You can also create a custom Caching Module Provider as explained in the [Create Caching Module Provider guide](#).
|
||||
|
||||
<Note>
|
||||
|
||||
The Caching Module is available starting [Medusa v2.11.0](https://github.com/medusajs/medusa/releases/tag/v2.11.0). It replaces the deprecated [Cache Module](./cache/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
<CardList
|
||||
items={[
|
||||
{
|
||||
title: "In-Memory",
|
||||
href: "/infrastructure-modules/cache/in-memory",
|
||||
badge: {
|
||||
variant: "neutral",
|
||||
children: "For Development"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Redis",
|
||||
href: "/infrastructure-modules/cache/redis",
|
||||
href: "/infrastructure-modules/caching/providers/redis",
|
||||
badge: {
|
||||
variant: "green",
|
||||
children: "For Production"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Memcached",
|
||||
// TODO add link
|
||||
href: "#",
|
||||
badge: {
|
||||
variant: "blue",
|
||||
children: "Tutorial"
|
||||
}
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user