- Split Module and Module Links to their own chapters - Add new docs on db operations and transactions in modules, multiple services, links with custom columns, etc... - Added a list of registered dependencies in a module container
114 lines
3.7 KiB
Plaintext
114 lines
3.7 KiB
Plaintext
export const metadata = {
|
|
title: `${pageNumber} Module Isolation`,
|
|
}
|
|
|
|
# {metadata.title}
|
|
|
|
In this chapter, you'll learn how modules are isolated, and what that means for your custom development.
|
|
|
|
<Note title="Summary">
|
|
|
|
- Modules can't access resources, such as services or data models, from other modules.
|
|
- Use Medusa's linking concepts, as explained in the [Module Links chapters](../../module-links/page.mdx), to extend a module's data models and retrieve data across modules.
|
|
|
|
</Note>
|
|
|
|
## How are Modules Isolated?
|
|
|
|
A module is unaware of any resources other than its own, such as services or data models. This means it can't access these resources if they're implemented in another module.
|
|
|
|
For example, your custom module can't resolve the Product Module's main service or have direct relationships from its data model to the Product Module's data models.
|
|
|
|
---
|
|
|
|
## Why are Modules Isolated
|
|
|
|
Some of the module isolation's benefits include:
|
|
|
|
- Integrate your module into any Medusa application without side-effects to your setup.
|
|
- Replace existing modules with your custom implementation, if your use case is drastically different.
|
|
- Use modules in other environments, such as Edge functions and Next.js apps.
|
|
|
|
---
|
|
|
|
## How to Extend Data Model of Another Module?
|
|
|
|
To extend the data model of another module, such as the `product` data model of the Product Module, use Medusa's linking concepts as explained in the [Module Links chapters](../../module-links/page.mdx).
|
|
|
|
---
|
|
|
|
## How to Use Services of Other Modules?
|
|
|
|
If you're building a feature that uses functionalities from different modules, use a workflow whose steps resolve the modules' services to perform these functionalities.
|
|
|
|
Workflows ensure data consistency through their roll-back mechanism and tracking of each execution's status, steps, input, and output.
|
|
|
|
### Example
|
|
|
|
For example, consider you have two modules:
|
|
|
|
1. A module that stores and manages brands in your application.
|
|
2. A module that integrates a third-party Content Management System (CMS).
|
|
|
|
To sync brands from your application to the third-party system, create the following steps:
|
|
|
|
export const stepsHighlights = [
|
|
["1", "retrieveBrandsStep", "A step that retrieves brands using a brand module."],
|
|
["14", "createBrandsInCmsStep", "A step that creates brands using a CMS module."],
|
|
["25", "", "Add a compensation function to the step if an error occurs."]
|
|
]
|
|
|
|
```ts title="Example Steps" highlights={stepsHighlights}
|
|
const retrieveBrandsStep = createStep(
|
|
"retrieve-brands",
|
|
async (_, { container }) => {
|
|
const brandModuleService = container.resolve(
|
|
"brandModuleService"
|
|
)
|
|
|
|
const brands = await brandModuleService.listBrands()
|
|
|
|
return new StepResponse(brands)
|
|
}
|
|
)
|
|
|
|
const createBrandsInCmsStep = createStep(
|
|
"create-brands-in-cms",
|
|
async ({ brands }, { container }) => {
|
|
const cmsModuleService = container.resolve(
|
|
"cmsModuleService"
|
|
)
|
|
|
|
const cmsBrands = await cmsModuleService.createBrands(brands)
|
|
|
|
return new StepResponse(cmsBrands, cmsBrands)
|
|
},
|
|
async (brands, { container }) => {
|
|
const cmsModuleService = container.resolve(
|
|
"cmsModuleService"
|
|
)
|
|
|
|
await cmsModuleService.deleteBrands(
|
|
brands.map((brand) => brand.id)
|
|
)
|
|
}
|
|
)
|
|
```
|
|
|
|
The `retrieveBrandsStep` retrieves the brands from a brand module, and the `createBrandsInCmsStep` creates the brands in a third-party system using a CMS module.
|
|
|
|
Then, create the following workflow that uses these steps:
|
|
|
|
```ts title="Example Workflow"
|
|
export const syncBrandsWorkflow = createWorkflow(
|
|
"sync-brands",
|
|
() => {
|
|
const brands = retrieveBrandsStep()
|
|
|
|
updateBrandsInCmsStep({ brands })
|
|
}
|
|
)
|
|
```
|
|
|
|
You can then use this workflow in an API route, scheduled job, or other resources that use this functionality.
|