Skip to content
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: revise medusa container chapter #10192

Merged
merged 1 commit into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
export const metadata = {
title: `${pageNumber} Module's Container`,
title: `${pageNumber} Module Container`,
}

# {metadata.title}

In this chapter, you'll learn about the module's container and how to resolve resources in that container.

## Module's Container

Since modules are isolated, each module has a local container only used by the resources of that module.

So, resources in the module, such as services or loaders, can only resolve other resources registered in the module's container.
Expand Down
178 changes: 158 additions & 20 deletions www/apps/book/app/learn/basics/medusa-container/page.mdx
Original file line number Diff line number Diff line change
@@ -1,46 +1,184 @@
export const metadata = {
title: `${pageNumber} Medusa container`,
title: `${pageNumber} Medusa Container`,
}

# {metadata.title}

In this chapter, you’ll learn about the Medusa container and how to use it.

## What is the Medusa container?
## What is the Medusa Container?

The Medusa container holds all resources registered in the Medusa application, such as services.
The Medusa container is a registry of framework and commerce tools that's accessible across your application. Medusa automatically registers these tools in the container, including custom ones that you've built, so that you can use them in your customizations.

In your customizations, you use the Medusa container to resolve these resources and use their functionalities.
In other platforms, if you have a resource A (for example, a class) that depends on a resource B, you have to manually add resource B to the container or specify it beforehand as A's dependency, which is often done in a file separate from A's code. This becomes difficult to manage as you maintain larger applications with many changing dependencies.

For example, in a custom API route you can resolve any service registered in the Medusa application using the `scope.resolve` method of the `MedusaRequest` parameter:
Medusa simplifies this process by giving you access to the container, with the tools or resources already registered, at all times in your customizations. When you reach a point in your code where you need a tool, you resolve it from the container and use it.

For example, consider you're creating an API route that retrieves products based on filters using [Query](../../advanced-development/module-links/query/page.mdx), a tool that fetches data across the application. In the API route's function, you can resolve Query from the container passed to the API route and use it:

export const highlights = [
["9", "resolve", "Resolve the Product Module's main service."],
["8", "resolve", "A method that resolves resources from the container."],
[
"10",
"Modules.PRODUCT",
"The resource registration name imported from `@medusajs/framework/utils`.",
"9",
"ContainerRegistrationKeys.QUERY",
"Query's registration key in the container.",
],
]

```ts highlights={highlights}
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
import { IProductModuleService } from "@medusajs/framework/types"
import { Modules } from "@medusajs/framework/utils"
import { MedusaRequest, MedusaResponse } from "@medusajs/framework";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";

export const GET = async (
req: MedusaRequest,
export async function GET(
req: MedusaRequest,
res: MedusaResponse
) => {
const productModuleService: IProductModuleService = req.scope.resolve(
Modules.PRODUCT
) {
const query = req.scope.resolve(
ContainerRegistrationKeys.QUERY
)

const [, count] = await productModuleService
.listAndCountProducts()
const { data: products } = await query.graph({
entity: "product",
fields: ["*"],
filters: {
id: "prod_123"
}
})

res.json({
count,
products
})
}
```

The API route accepts as a first parameter a request object that has a `scope` property, which is the Medusa container. It has a `resolve` method that resolves a resource from the container by the key it's registered with.

To resolve Query, you use the `ContainerRegistrationKeys` enum imported from `@medusajs/framework/utils`, which has the registration keys for all framework tools and resources.

<Note>

You can learn more about how Query works in [this chapter](../../advanced-development/module-links/query/page.mdx).

</Note>

---

## List of Resources Registered in the Medusa Container

Find a full list of the registered resources and their registration key in [this reference](!resources!/resources/medusa-container-resources)

---

## How to Resolve From the Medusa Container

This section gives quick examples of how to resolve resources from the Medusa container in customizations other than an API route, which is covered in the section above.

### Subscriber

A [subscriber](../events-and-subscribers/page.mdx) function, which is executed when an event is emitted, accepts as a parameter an object with a `container` property, whose value is the Medusa container. Use its `resolve` method to resolve a resource by its registration key:

export const subscriberHighlights = [
["6", "container", "Receive the Medusa container as a parameter"],
["8", "resolve", "Resolve a resource from the container by its key"]
]

```ts highlights={subscriberHighlights}
import { SubscriberArgs, type SubscriberConfig } from "@medusajs/framework"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";

export default async function productCreateHandler({
event: { data },
container,
}: SubscriberArgs<{ id: string }>) {
const query = container.resolve(ContainerRegistrationKeys.QUERY)

const { data: products } = await query.graph({
entity: "product",
fields: ["*"],
filters: {
id: data.id
}
})

console.log(`You created a product with the title ${products[0].title}`)
}

export const config: SubscriberConfig = {
event: `product.created`,
}
```

### Scheduled Job

A [scheduled job](../scheduled-jobs/page.mdx) function, which is executed at a specified interval, accepts the Medusa container as a parameter. Use its `resolve` method to resolve a resource by its registration key:

export const scheduledJobHighlights = [
["5", "container", "Receive the Medusa container as a parameter"],
["7", "resolve", "Resolve a resource from the container by its key"]
]

```ts highlights={scheduledJobHighlights}
import { MedusaContainer } from "@medusajs/framework/types"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";

export default async function myCustomJob(
container: MedusaContainer
) {
const query = container.resolve(ContainerRegistrationKeys.QUERY)

const { data: products } = await query.graph({
entity: "product",
fields: ["*"],
filters: {
id: "prod_123"
}
})

console.log(
`You have ${products.length} matching your filters.`
)
}

export const config = {
name: "every-minute-message",
// execute every minute
schedule: "* * * * *",
}
```

### Workflow Step

A [step in a workflow](../workflows/page.mdx), which is a special function where you build reliable business logic, accepts in its second parameter a `container` property, whose value is the Medusa container. Use its `resolve` method to resolve a resource by its registration key:

export const workflowStepsHighlight = [
["7", "container", "Receive the Medusa container as a parameter"],
["8", "resolve", "Resolve a resource from the container by its key"]
]

```ts highlights={workflowStepsHighlight}
import {
createStep,
StepResponse,
} from "@medusajs/framework/workflows-sdk"
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";

const step1 = createStep("step-1", async (_, { container }) => {
const query = container.resolve(ContainerRegistrationKeys.QUERY)

const { data: products } = await query.graph({
entity: "product",
fields: ["*"],
filters: {
id: "prod_123"
}
})

return new StepResponse(products)
})
```

### Module Services and Loaders

A [module](../modules/page.mdx), which is a package of functionalities for a single feature or domain, has its own container, so it can't resolve resources from the Medusa container.

Learn more about the module's container in [this chapter](../../advanced-development/modules/container/page.mdx).
4 changes: 2 additions & 2 deletions www/apps/book/generated/edit-dates.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ export const generatedEditDates = {
"app/learn/advanced-development/page.mdx": "2024-07-04T17:26:03+03:00",
"app/learn/first-customizations/page.mdx": "2024-09-11T10:48:42.374Z",
"app/learn/debugging-and-testing/page.mdx": "2024-05-03T17:36:38+03:00",
"app/learn/basics/medusa-container/page.mdx": "2024-09-30T08:43:53.132Z",
"app/learn/basics/medusa-container/page.mdx": "2024-11-21T08:53:18.181Z",
"app/learn/basics/project-directories-files/page.mdx": "2024-10-03T12:46:52.762Z",
"app/learn/basics/api-routes/page.mdx": "2024-09-11T10:48:31.777Z",
"app/learn/basics/modules-directory-structure/page.mdx": "2024-10-03T13:03:35.957Z",
"app/learn/advanced-development/workflows/access-workflow-errors/page.mdx": "2024-09-18T12:54:04.695Z",
"app/learn/basics/events-and-subscribers/page.mdx": "2024-09-30T08:43:53.131Z",
"app/learn/advanced-development/modules/container/page.mdx": "2024-09-30T08:43:53.125Z",
"app/learn/advanced-development/modules/container/page.mdx": "2024-11-21T08:59:18.707Z",
"app/learn/advanced-development/workflows/execute-another-workflow/page.mdx": "2024-09-30T08:43:53.129Z",
"app/learn/basics/loaders/page.mdx": "2024-09-03T08:00:45.993Z",
"app/learn/advanced-development/admin/widgets/page.mdx": "2024-10-07T12:51:09.969Z",
Expand Down
2 changes: 1 addition & 1 deletion www/apps/book/sidebar.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ export const sidebar = numberSidebarItems(
{
type: "link",
path: "/learn/advanced-development/modules/container",
title: "Module's Container",
title: "Module Container",
},
{
type: "link",
Expand Down
24 changes: 18 additions & 6 deletions www/apps/resources/app/medusa-container-resources/page.mdx
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import { Table } from "docs-ui"

export const metadata = {
title: `Medusa and Module Container Dependencies`,
title: `Medusa and Module Container Resources`,
}

# {metadata.title}

This documentation page includes the list of dependencies registered in the container of the Medusa application and a module.
This documentation page includes the list of resources registered in the container of the Medusa application and modules.

## Medusa Container Dependencies
## Medusa Container Resources

The following list of dependencies are resources that can be resolved by all resources (such as API route or workflow) except of a module's.
The following table has a list of all resources that you can resolve in your customizations outside a module (such as API routes or workflows).

<Note>

Learn more about the Medusa Container in [this documentation](!docs!/learn/basics/medusa-container).

</Note>

<Note title="Tip">

Use the `ContainerRegistrationKeys` enum imported from `@medusajs/framework/utils` where specified.

</Note>
Expand Down Expand Up @@ -135,9 +141,15 @@ Use the `ContainerRegistrationKeys` enum imported from `@medusajs/framework/util

---

## Module Container Dependencies
## Module Container Resources

The following table has a list of all resources that you can resolve in a module's services or loaders.

The following resources are resources that can be resolved by a module's services and loaders.
<Note>

Learn more about the Module Container in [this documentation](!docs!/learn/advanced-development/modules/container).

</Note>

<Note>

Expand Down
2 changes: 1 addition & 1 deletion www/apps/resources/generated/edit-dates.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export const generatedEditDates = {
"app/deployment/page.mdx": "2024-07-25T09:55:22+03:00",
"app/integrations/page.mdx": "2024-11-19T10:09:54.075Z",
"app/medusa-cli/page.mdx": "2024-08-28T11:25:32.382Z",
"app/medusa-container-resources/page.mdx": "2024-09-30T08:43:53.173Z",
"app/medusa-container-resources/page.mdx": "2024-11-21T08:59:01.120Z",
"app/medusa-workflows-reference/page.mdx": "2024-09-30T08:43:53.174Z",
"app/nextjs-starter/page.mdx": "2024-07-01T10:21:19+03:00",
"app/recipes/b2b/page.mdx": "2024-10-03T13:07:44.153Z",
Expand Down
Loading