- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
Query Context
In this chapter, you'll learn how to pass contexts when retrieving data with Query.
What is Query Context?#
Query context is a way to pass additional information when retrieving data with Query. This data can be useful when applying custom transformations to the retrieved data based on the current context.
For example, consider you have a Blog Module with posts and authors. You can accept the user's language as a context and return the posts in the user's language. Another example is how Medusa uses Query Context to retrieve product variants' prices based on the customer's currency.
How to Use Query Context#
The query.graph
method accepts an optional context
parameter that can be used to pass additional context either to the data model you're retrieving (for example, post
), or its related and linked models (for example, author
).
You initialize a context using QueryContext
from the Modules SDK. It accepts an object of contexts as an argument.
For example, to retrieve posts using Query while passing the user's language as a context:
In this example, you pass in the context a lang
property whose value is es
.
Then, to handle the context while retrieving records of the data model, in the associated module's service you override the generated list
method of the data model.
For example, continuing the example above, you can override the listPosts
method of the Blog Module's service to handle the context:
1import { MedusaContext, MedusaService } from "@medusajs/framework/utils"2import { Context, FindConfig } from "@medusajs/framework/types"3import Post from "./models/post"4import Author from "./models/author"5 6class BlogModuleService extends MedusaService({7 Post,8 Author9}){10 // @ts-ignore11 async listPosts(12 filters?: any, 13 config?: FindConfig<any> | undefined, 14 @MedusaContext() sharedContext?: Context | undefined15 ) {16 const context = filters.context ?? {}17 delete filters.context18 19 let posts = await super.listPosts(filters, config, sharedContext)20 21 if (context.lang === "es") {22 posts = posts.map((post) => {23 return {24 ...post,25 title: post.title + " en español",26 }27 })28 }29 30 return posts31 }32}33 34export default BlogModuleService
In the above example, you override the generated listPosts
method. This method receives as a first parameter the filters passed to the query, but it also includes a context
property that holds the context passed to the query.
You extract the context from filters
, then retrieve the posts using the parent's listPosts
method. After that, if the language is set in the context, you transform the titles of the posts.
All posts returned will now have their titles appended with "en español".
Passing Query Context to Related Data Models#
If you're retrieving a data model and you want to pass context to its associated model in the same module, you can pass them as part of QueryContext
's parameter, then handle them in the same list
method.
For example, to pass a context for the post's authors:
Then, in the listPosts
method, you can handle the context for the post's authors:
1import { MedusaContext, MedusaService } from "@medusajs/framework/utils"2import { Context, FindConfig } from "@medusajs/framework/types"3import Post from "./models/post"4import Author from "./models/author"5 6class BlogModuleService extends MedusaService({7 Post,8 Author9}){10 // @ts-ignore11 async listPosts(12 filters?: any, 13 config?: FindConfig<any> | undefined, 14 @MedusaContext() sharedContext?: Context | undefined15 ) {16 const context = filters.context ?? {}17 delete filters.context18 19 let posts = await super.listPosts(filters, config, sharedContext)20 21 const isPostLangEs = context.lang === "es"22 const isAuthorLangEs = context.author?.lang === "es"23 24 if (isPostLangEs || isAuthorLangEs) {25 posts = posts.map((post) => {26 return {27 ...post,28 title: isPostLangEs ? post.title + " en español" : post.title,29 author: {30 ...post.author,31 name: isAuthorLangEs ? post.author.name + " en español" : post.author.name,32 }33 }34 })35 }36 37 return posts38 }39}40 41export default BlogModuleService
The context in filters
will also have the context for author
, which you can use to make transformations to the post's authors.
Passing Query Context to Linked Data Models#
If you're retrieving a data model and you want to pass context to a linked model in a different module, pass to the context
property an object instead, where its keys are the linked model's name and the values are the context for that linked model.
For example, consider the Product Module's Product
data model is linked to the Blog Module's Post
data model. You can pass context to the Post
data model while retrieving products like so:
In this example, you retrieve products and their associated posts. You also pass a context for post
, indicating the customer's language.
To handle the context, you override the generated listPosts
method of the Blog Module as explained previously.