- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
3.1. 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:
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("query")9 10 const { data: products } = await query.graph({11 entity: "product",12 fields: ["*"],13 filters: {14 id: "prod_123",15 },16 })17 18 res.json({19 products,20 })21}
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.
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:
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:
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 durable execution logic across multiple modules, 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:
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.