docs: rename Architectural Modules to Infrastructure Modules (#12212)
* docs: rename Architectural Modules to Infrastructure Modules * generate again
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
---
|
||||
sidebar_label: "Create Cache Module"
|
||||
tags:
|
||||
- cache
|
||||
- how to
|
||||
- server
|
||||
---
|
||||
|
||||
export const metadata = {
|
||||
title: `How to Create a Cache Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this guide, you’ll learn how to create a Cache Module.
|
||||
|
||||
## 1. Create Module Directory
|
||||
|
||||
Start by creating a new directory for your module. For example, `src/modules/my-cache`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Create the Cache Service
|
||||
|
||||
Create the file `src/modules/my-cache/service.ts` that holds the implementation of the cache service.
|
||||
|
||||
The Cache Module's main service must implement the `ICacheService` interface imported from `@medusajs/framework/types`:
|
||||
|
||||
```ts title="src/modules/my-cache/service.ts"
|
||||
import { ICacheService } from "@medusajs/framework/types"
|
||||
|
||||
class MyCacheService implements ICacheService {
|
||||
get<T>(key: string): Promise<T> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
set(key: string, data: unknown, ttl?: number): Promise<void> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
invalidate(key: string): Promise<void> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
}
|
||||
|
||||
export default MyCacheService
|
||||
```
|
||||
|
||||
The service implements the required methods based on the desired caching mechanism.
|
||||
|
||||
### Implement get Method
|
||||
|
||||
The `get` method retrieves the value of a cached item based on its key.
|
||||
|
||||
The method accepts a string as a first parameter, which is the key in the cache. It either returns the cached item or `null` if it doesn’t exist.
|
||||
|
||||
For example, to implement this method using Memcached:
|
||||
|
||||
```ts title="src/modules/my-cache/service.ts"
|
||||
class MyCacheService implements ICacheService {
|
||||
// ...
|
||||
async get<T>(cacheKey: string): Promise<T | null> {
|
||||
return new Promise((res, rej) => {
|
||||
this.memcached.get(cacheKey, (err, data) => {
|
||||
if (err) {
|
||||
res(null)
|
||||
} else {
|
||||
if (data) {
|
||||
res(JSON.parse(data))
|
||||
} else {
|
||||
res(null)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Implement set Method
|
||||
|
||||
The `set` method is used to set an item in the cache. It accepts three parameters:
|
||||
|
||||
1. The first parameter is a string indicating the key of the data being added to the cache. This key can be used later to get or invalidate the cached item.
|
||||
2. The second parameter is the data to be added to the cache. The data can be of any type.
|
||||
3. The third parameter is optional. It’s a number indicating how long (in seconds) the data should be kept in the cache.
|
||||
|
||||
For example, to implement this method using Memcached:
|
||||
|
||||
```ts title="src/modules/my-cache/service.ts"
|
||||
class MyCacheService implements ICacheService {
|
||||
protected TTL = 60
|
||||
// ...
|
||||
async set(
|
||||
key: string,
|
||||
data: Record<string, unknown>,
|
||||
ttl: number = this.TTL // or any value
|
||||
): Promise<void> {
|
||||
return new Promise((res, rej) =>
|
||||
this.memcached.set(
|
||||
key, JSON.stringify(data), ttl, (err) => {
|
||||
if (err) {
|
||||
rej(err)
|
||||
} else {
|
||||
res()
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Implement invalidate Method
|
||||
|
||||
The `invalidate` method removes an item from the cache using its key.
|
||||
|
||||
By default, items are removed from the cache when their time-to-live (ttl) expires. The `invalidate` method can be used to remove the item beforehand.
|
||||
|
||||
The method accepts a string as a first parameter, which is the key of the item to invalidate and remove from the cache.
|
||||
|
||||
For example, to implement this method using Memcached:
|
||||
|
||||
```ts title="src/modules/my-cache/service.ts"
|
||||
class MyCacheService implements ICacheService {
|
||||
// ...
|
||||
async invalidate(key: string): Promise<void> {
|
||||
return new Promise((res, rej) => {
|
||||
this.memcached.del(key, (err) => {
|
||||
if (err) {
|
||||
rej(err)
|
||||
} else {
|
||||
res()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Create Module Definition File
|
||||
|
||||
Create the file `src/modules/my-cache/index.ts` with the following content:
|
||||
|
||||
```ts title="src/modules/my-cache/index.ts"
|
||||
import MyCacheService from "./service"
|
||||
import { Module } from "@medusajs/framework/utils"
|
||||
|
||||
export default Module("my-cache", {
|
||||
service: MyCacheService,
|
||||
})
|
||||
```
|
||||
|
||||
This exports the module's definition, indicating that the `MyCacheService` is the main service of the module.
|
||||
|
||||
---
|
||||
|
||||
## 4. Use Module
|
||||
|
||||
To use your Cache Module, add it to the `modules` object exported as part of the configurations in `medusa-config.ts`. A Cache Module is added under the `cacheService` key.
|
||||
|
||||
For example:
|
||||
|
||||
```ts title="medusa-config.ts"
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
|
||||
// ...
|
||||
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
{
|
||||
resolve: "./src/modules/my-cache",
|
||||
options: {
|
||||
// any options
|
||||
ttl: 30,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
@@ -0,0 +1,73 @@
|
||||
import { Table } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `In-Memory Cache Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The In-Memory Cache Module uses a plain JavaScript Map object to store the cached data. This module is used by default in your Medusa application.
|
||||
|
||||
This module is helpful for development or when you’re testing out Medusa, but it’s not recommended to be used in production.
|
||||
|
||||
For production, it’s recommended to use modules like [Redis Cache Module](../redis/page.mdx).
|
||||
|
||||
---
|
||||
|
||||
## Register the In-Memory Cache Module
|
||||
|
||||
<Note>
|
||||
|
||||
The In-Memory Cache Module is registered by default in your application.
|
||||
|
||||
</Note>
|
||||
|
||||
Add the module into the `modules` property of the exported object in `medusa-config.ts`:
|
||||
|
||||
```ts title="medusa-config.ts"
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
// ...
|
||||
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/cache-inmemory",
|
||||
options: {
|
||||
// optional options
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
### In-Memory Cache 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>
|
||||
|
||||
`ttl`
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
The number of seconds an item can live in the cache before it’s removed.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
`30` seconds
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
@@ -0,0 +1,86 @@
|
||||
import { CardList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Cache Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this document, you'll learn what a Cache Module is and how to use it in your Medusa application.
|
||||
|
||||
## What is a Cache Module?
|
||||
|
||||
A Cache Module is used to cache the results of computations such as price selection or various tax calculations.
|
||||
|
||||
The underlying database, third-party service, or caching logic is flexible since it's implemented in a module. You can choose from Medusa’s cache modules or create your own to support something more suitable for your architecture.
|
||||
|
||||
### Default Cache Module
|
||||
|
||||
By default, Medusa uses the [In-Memory Cache Module](./in-memory/page.mdx). This module uses a plain JavaScript Map object to store the cache data. While this is suitable for development, it's recommended to use other Cache Modules, such as the [Redis Cache Module](./redis/page.mdx), for production. You can also [Create a Cache Module](./create/page.mdx).
|
||||
|
||||
---
|
||||
|
||||
## How to Use the Cache Module?
|
||||
|
||||
You can use the registered Cache Module as part of the [workflows](!docs!/learn/fundamentals/workflows) you build for your custom features. A workflow is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism.
|
||||
|
||||
In a step of your workflow, you can resolve the Cache Module's service and use its methods to cache data, retrieve cached data, or clear the cache.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
import {
|
||||
createStep,
|
||||
createWorkflow,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
const step1 = createStep(
|
||||
"step-1",
|
||||
async ({}, { container }) => {
|
||||
const cacheModuleService = container.resolve(
|
||||
Modules.CACHE
|
||||
)
|
||||
|
||||
await cacheModuleService.set("key", "value")
|
||||
}
|
||||
)
|
||||
|
||||
export const workflow = createWorkflow(
|
||||
"workflow-1",
|
||||
() => {
|
||||
step1()
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
In the example above, you create a workflow that has a step. In the step, you resolve the service of the Cache Module from the [Medusa container](!docs!/learn/fundamentals/medusa-container).
|
||||
|
||||
Then, you use the `set` method of the Cache Module to cache the value `"value"` with the key `"key"`.
|
||||
|
||||
---
|
||||
|
||||
## List of Cache Modules
|
||||
|
||||
Medusa provides the following Cache Modules. You can use one of them, or [Create a Cache Module](./create/page.mdx).
|
||||
|
||||
<CardList
|
||||
items={[
|
||||
{
|
||||
title: "In-Memory",
|
||||
href: "/infrastructure-modules/cache/in-memory",
|
||||
badge: {
|
||||
variant: "neutral",
|
||||
children: "For Development"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Redis",
|
||||
href: "/infrastructure-modules/cache/redis",
|
||||
badge: {
|
||||
variant: "green",
|
||||
children: "For Production"
|
||||
}
|
||||
}
|
||||
]}
|
||||
/>
|
||||
@@ -0,0 +1,171 @@
|
||||
import { Table, Prerequisites } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Redis Cache Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The Redis Cache Module uses Redis to cache data in your store. In production, it's recommended to use this module.
|
||||
|
||||
---
|
||||
|
||||
## Register the Redis Cache Module
|
||||
|
||||
<Prerequisites items={[
|
||||
{
|
||||
text: "Redis installed and Redis server running",
|
||||
link: "https://redis.io/docs/getting-started/installation/"
|
||||
}
|
||||
]} />
|
||||
|
||||
Add the module into the `modules` property of the exported object in `medusa-config.ts`:
|
||||
|
||||
export const highlights = [
|
||||
["11", "redisUrl", "The Redis connection URL."]
|
||||
]
|
||||
|
||||
```ts title="medusa-config.ts" highlights={highlights}
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
|
||||
// ...
|
||||
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/cache-redis",
|
||||
options: {
|
||||
redisUrl: process.env.CACHE_REDIS_URL,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Make sure to add the following environment variables:
|
||||
|
||||
```bash
|
||||
CACHE_REDIS_URL=<YOUR_REDIS_URL>
|
||||
```
|
||||
|
||||
### Redis Cache Module Options
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Option</Table.HeaderCell>
|
||||
<Table.HeaderCell>Description</Table.HeaderCell>
|
||||
<Table.HeaderCell>Required</Table.HeaderCell>
|
||||
<Table.HeaderCell>Default</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
|
||||
`redisUrl`
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
A string indicating the Redis connection URL.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
Yes
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
|
||||
`redisOptions`
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
An object of Redis options. Refer to the [Redis API Reference](https://redis.github.io/ioredis/index.html#RedisOptions) for details on accepted properties.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
No
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
|
||||
`ttl`
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
The number of seconds an item can live in the cache before it’s removed.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
No
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
`30` seconds
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
|
||||
`namespace`
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
A string used to prefix all cached keys with `{namespace}:`.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
No
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
`medusa`. So, all cached keys are prefixed with `medusa:`.
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
---
|
||||
|
||||
## Test the Module
|
||||
|
||||
To test the module, start the Medusa application:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run dev
|
||||
```
|
||||
|
||||
You'll see the following message in the terminal's logs:
|
||||
|
||||
```bash noCopy noReport
|
||||
Connection to Redis in module 'cache-redis' established
|
||||
```
|
||||
Reference in New Issue
Block a user