2.2. Medusa Container

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

What is the Medusa Container?#

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 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.

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, 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:

Code
1import { MedusaRequest, MedusaResponse } from "@medusajs/framework"2import { ContainerRegistrationKeys } from "@medusajs/framework/utils"3
4export async function GET(5  req: MedusaRequest,6  res: MedusaResponse7) {8  const query = req.scope.resolve(9    ContainerRegistrationKeys.QUERY10  )11
12  const { data: products } = await query.graph({13    entity: "product",14    fields: ["*"],15    filters: {16      id: "prod_123",17    },18  })19
20  res.json({21    products,22  })23}

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.

NoteYou can learn more about how Query works in this chapter .

List of Resources Registered in the Medusa Container#

Find a full list of the registered resources and their registration key in this reference


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 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:

Code
1import { SubscriberArgs, type SubscriberConfig } from "@medusajs/framework"2import { ContainerRegistrationKeys } from "@medusajs/framework/utils"3
4export default async function productCreateHandler({5  event: { data },6  container,7}: SubscriberArgs<{ id: string }>) {8  const query = container.resolve(ContainerRegistrationKeys.QUERY)9
10  const { data: products } = await query.graph({11    entity: "product",12    fields: ["*"],13    filters: {14      id: data.id,15    },16  })17
18  console.log(`You created a product with the title ${products[0].title}`)19}20
21export const config: SubscriberConfig = {22  event: `product.created`,23}

Scheduled Job#

A scheduled job 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:

Code
1import { MedusaContainer } from "@medusajs/framework/types"2import { ContainerRegistrationKeys } from "@medusajs/framework/utils"3
4export default async function myCustomJob(5  container: MedusaContainer6) {7  const query = container.resolve(ContainerRegistrationKeys.QUERY)8
9  const { data: products } = await query.graph({10    entity: "product",11    fields: ["*"],12    filters: {13      id: "prod_123",14    },15  })16
17  console.log(18    `You have ${products.length} matching your filters.`19  )20}21
22export const config = {23  name: "every-minute-message",24  // execute every minute25  schedule: "* * * * *",26}

Workflow Step#

A step in a workflow, 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:

Code
1import {2  createStep,3  StepResponse,4} from "@medusajs/framework/workflows-sdk"5import { ContainerRegistrationKeys } from "@medusajs/framework/utils"6
7const step1 = createStep("step-1", async (_, { container }) => {8  const query = container.resolve(ContainerRegistrationKeys.QUERY)9
10  const { data: products } = await query.graph({11    entity: "product",12    fields: ["*"],13    filters: {14      id: "prod_123",15    },16  })17
18  return new StepResponse(products)19})

Module Services and Loaders#

A module, 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.

Was this chapter helpful?
Edit this page