import { TypeList, Tabs, TabsList, TabsTrigger, TabsContent, TabsContentWrapper } from "docs-ui" export const metadata = { title: `${pageNumber} Remote Query`, } # {metadata.title} In this chapter, you’ll learn about the remote query and how to use it to fetch data from modules. ## What is the Remote Query? The remote query fetches data across modules. It’s a function registered in the Medusa container under the `remoteQuery` key. In your resources, such as API routes or workflows, you can resolve the remote query to fetch data across custom modules and Medusa’s commerce modules. - [Enable the isQueryable configuration of the module](../module-links/page.mdx#prerequisite-isqueryable-configuration) --- ## Remote Query Example For example, create the route `src/api/store/query/route.ts` with the following content: export const exampleHighlights = [ ["18", "", "Resolve the remote query from the Medusa container."], ["21", "remoteQueryObjectFromString", "Utility function to build the query."], ["22", "entryPoint", "The name of the data model you're querying."], ["23", "fields", "An array of the data model’s properties to retrieve in the result."], ["27", "remoteQuery", "Run the query using the remote query."] ] ```ts title="src/api/store/query/route.ts" highlights={exampleHighlights} apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/query" collapsibleLines="1-12" expandButtonLabel="Show Imports" import { MedusaRequest, MedusaResponse, } from "@medusajs/medusa" import { remoteQueryObjectFromString, ContainerRegistrationKeys, } from "@medusajs/utils" import type { RemoteQueryFunction, } from "@medusajs/modules-sdk" export async function GET( req: MedusaRequest, res: MedusaResponse ): Promise { const remoteQuery: RemoteQueryFunction = req.scope.resolve( ContainerRegistrationKeys.REMOTE_QUERY ) const query = remoteQueryObjectFromString({ entryPoint: "my_custom", fields: ["id", "name"], }) res.json({ my_customs: await remoteQuery(query), }) } ``` In the above example, you resolve `remoteQuery` from the Medusa container. Then, you create a query using the `remoteQueryObjectFromString` utility function imported from `@medusajs/utils`. This function accepts as a parameter an object with the following required properties: - `entryPoint`: The data model's name, as specified in the first parameter of the `model.define` method used for the data model's definition. - `fields`: An array of the data model’s properties to retrieve in the result. You then pass the query to the `remoteQuery` function to retrieve the results. --- ## Retrieve Linked Records Retrieve the records of a linked data model by passing in `fields` the data model's name suffixed with `.*`. For example: ```ts highlights={[["6"]]} const query = remoteQueryObjectFromString({ entryPoint: "my_custom", fields: [ "id", "name", "product.*" ], }) ``` `.*` means that all of data model's properties should be retrieved. To retrieve a specific property, replace the `*` with the property's name. For example, `product.title`. ### Retrieve List Link Records If the linked data model has `isList` enabled in the link definition, pass in `fields` the data model's plural name suffixed with `.*`. For example: ```ts highlights={[["6"]]} const query = remoteQueryObjectFromString({ entryPoint: "my_custom", fields: [ "id", "name", "products.*" ], }) ``` --- ## Apply Filters ```ts highlights={[["6"], ["7"], ["8"], ["9"]]} const query = remoteQueryObjectFromString({ entryPoint: "my_custom", fields: ["id", "name"], variables: { filters: { id: [ "mc_01HWSVWR4D2XVPQ06DQ8X9K7AX", "mc_01HWSVWK3KYHKQEE6QGS2JC3FX", ], }, }, }) const result = await remoteQuery(query) ``` The `remoteQueryObjectFromString` function accepts a `variables` property. You can use this property to filter retrieved records. --- ## Sort Records ```ts highlights={[["5"], ["6"], ["7"]]} const query = remoteQueryObjectFromString({ entryPoint: "my_custom", fields: ["id", "name"], variables: { order: { name: "DESC", }, }, }) const result = await remoteQuery(query) ``` To sort returned records, pass an `order` property to `variables`. The `order` property is an object whose keys are property names, and values are either: - `ASC` to sort records by that property in ascending order. - `DESC` to sort records by that property in descending order. --- ## Apply Pagination ```ts highlights={[["5", "skip", "The number of records to skip before fetching the results."], ["6", "take", "The number of records to fetch."]]} const query = remoteQueryObjectFromString({ entryPoint: "my_custom", fields: ["id", "name"], variables: { skip: 0, take: 10, }, }) const { rows, metadata: { count, take, skip }, } = await remoteQuery(query) ``` To paginate the returned records, pass the following properties to `variables`: - `skip`: (required to apply pagination) The number of records to skip before fetching the results. - `take`: The number of records to fetch. When the pagination fields are provided, the `remoteQuery` returns an object having two properties: --- ## Using GraphQL The remote query function alternatively accepts a string with GraphQL syntax as the query. Basic Usage Apply Filters Sort Records Apply Pagination ### Basic GraphQL usage ```ts title="src/api/store/query/route.ts" apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/query" collapsibleLines="1-10" expandButtonLabel="Show Imports" import { MedusaRequest, MedusaResponse, } from "@medusajs/medusa" import { ContainerRegistrationKeys } from "@medusajs/utils" import type { RemoteQueryFunction, } from "@medusajs/modules-sdk" export async function GET( req: MedusaRequest, res: MedusaResponse ): Promise { const remoteQuery: RemoteQueryFunction = req.scope.resolve( ContainerRegistrationKeys.REMOTE_QUERY ) const query = ` query { my_custom { id name } } ` const result = await remoteQuery(query) res.json({ my_customs: result, }) } ``` ### Apply Filters with GraphQL The `remoteQuery` function accepts as a second parameter an object of variables to reference in the GraphQL query. ```ts highlights={[["2"], ["3"], ["13"], ["14"], ["15"], ["16"]]} const query = ` query($id: ID) { my_custom(id: $id) { id name } } ` const result = await remoteQuery( query, { id: [ "mc_01HWSVWR4D2XVPQ06DQ8X9K7AX", "mc_01HWSVWK3KYHKQEE6QGS2JC3FX", ] } ) ``` ### Sort Records with GraphQL To sort the records by a property, pass in the query an `order` argument whose value is an object. The object’s key is the property’s name, and the value is either: - `ASC` to sort items by that property in ascending order. - `DESC` to sort items by that property in descending order. For example: ```ts highlights={[["3"]]} const query = ` query { my_custom(order: {name: DESC}) { id name } } ` const result = await remoteQuery(query) ``` ### Pagination with GraphQL To paginate the records retrieved, pass a `skip` and `take` records in your query, and pass their values in the second parameter of the `remoteQuery` function. For example: ```ts highlights={[["2"], ["3"]]} const query = ` query($skip: Int, $take: Int) { my_custom(skip: $skip, take: $take) { id name } } ` const { rows, metadata: { count, take, skip } } = await remoteQuery( query, { skip: 0, take: 10 } ) ``` This skips no records and returns the first `10` records. When the pagination fields are provided, the `remoteQuery` returns an object having two properties: