From e9b5f76f9a9385df53475e1af53cb6364a02a7d8 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Tue, 10 Sep 2024 15:31:47 +0300 Subject: [PATCH] docs: add Query documentation (#9079) - Replace remote query documentation with new Query documentation - Add redirect from old remote query to new query documentation - Update remote query usages across docs to use new query usage. --- .../admin/constraints/page.mdx | 2 +- .../advanced-development/admin/tips/page.mdx | 2 +- .../api-routes/errors/page.mdx | 6 +- .../api-routes/protected-routes/page.mdx | 2 +- .../api-routes/responses/page.mdx | 10 +- .../api-routes/validation/page.mdx | 12 +- .../data-models/manage-relationships/page.mdx | 2 +- .../emit-event/page.mdx | 8 +- .../modules/query/page.mdx | 237 ++++++++++ .../modules/remote-query/page.mdx | 410 ------------------ .../workflows/workflow-hooks/page.mdx | 6 +- .../integration-tests/api-routes/page.mdx | 24 +- .../testing-tools/integration-tests/page.mdx | 2 +- .../integration-tests/workflows/page.mdx | 4 +- .../modules-tests/module-example/page.mdx | 2 +- .../testing-tools/modules-tests/page.mdx | 6 +- .../testing-tools/page.mdx | 4 +- www/apps/book/generated/edit-dates.mjs | 28 +- www/apps/book/next.config.mjs | 9 + www/apps/book/sidebar.mjs | 4 +- .../product/guides/price-with-taxes/page.mdx | 23 +- .../product/guides/price/page.mdx | 24 +- .../app/medusa-container-resources/page.mdx | 18 +- .../examples/standard/page.mdx | 68 ++- .../app/recipes/digital-products/page.mdx | 10 +- .../examples/restaurant-delivery/page.mdx | 47 +- .../marketplace/examples/vendors/page.mdx | 40 +- .../subscriptions/examples/standard/page.mdx | 56 ++- .../methods/list/page.mdx | 2 +- .../methods/listAndCount/page.mdx | 2 +- .../methods/retrieve/page.mdx | 2 +- 31 files changed, 437 insertions(+), 635 deletions(-) create mode 100644 www/apps/book/app/advanced-development/modules/query/page.mdx delete mode 100644 www/apps/book/app/advanced-development/modules/remote-query/page.mdx diff --git a/www/apps/book/app/advanced-development/admin/constraints/page.mdx b/www/apps/book/app/advanced-development/admin/constraints/page.mdx index 37ee2c7e9c..1433475846 100644 --- a/www/apps/book/app/advanced-development/admin/constraints/page.mdx +++ b/www/apps/book/app/advanced-development/admin/constraints/page.mdx @@ -17,7 +17,7 @@ export const arrowHighlights = [ ```ts highlights={arrowHighlights} // Don't -function ProductWidget () { +function ProductWidget() { // ... } diff --git a/www/apps/book/app/advanced-development/admin/tips/page.mdx b/www/apps/book/app/advanced-development/admin/tips/page.mdx index 9ece173e70..ca7179c5f8 100644 --- a/www/apps/book/app/advanced-development/admin/tips/page.mdx +++ b/www/apps/book/app/advanced-development/admin/tips/page.mdx @@ -31,7 +31,7 @@ const ProductWidget = () => { } fetch(`/admin/products`, { - credentials: "include" + credentials: "include", }) .then((res) => res.json()) .then(({ count }) => { diff --git a/www/apps/book/app/advanced-development/api-routes/errors/page.mdx b/www/apps/book/app/advanced-development/api-routes/errors/page.mdx index 526e59a8d6..f4b09b6b0f 100644 --- a/www/apps/book/app/advanced-development/api-routes/errors/page.mdx +++ b/www/apps/book/app/advanced-development/api-routes/errors/page.mdx @@ -256,7 +256,7 @@ import { defineMiddlewares, MedusaNextFunction, MedusaRequest, - MedusaResponse + MedusaResponse, } from "@medusajs/medusa" import { MedusaError } from "@medusajs/utils" @@ -268,9 +268,9 @@ export default defineMiddlewares({ next: MedusaNextFunction ) => { res.status(400).json({ - error: "Something happened." + error: "Something happened.", }) - } + }, }) ``` diff --git a/www/apps/book/app/advanced-development/api-routes/protected-routes/page.mdx b/www/apps/book/app/advanced-development/api-routes/protected-routes/page.mdx index de78e2b806..8e1539e3f5 100644 --- a/www/apps/book/app/advanced-development/api-routes/protected-routes/page.mdx +++ b/www/apps/book/app/advanced-development/api-routes/protected-routes/page.mdx @@ -83,7 +83,7 @@ For example: ```ts title="src/api/admin/custom/route.ts" highlights={[["15"]]} import type { AuthenticatedMedusaRequest, - MedusaResponse + MedusaResponse, } from "@medusajs/medusa" export const GET = async ( diff --git a/www/apps/book/app/advanced-development/api-routes/responses/page.mdx b/www/apps/book/app/advanced-development/api-routes/responses/page.mdx index 20a42f1a6a..45ea20b3dc 100644 --- a/www/apps/book/app/advanced-development/api-routes/responses/page.mdx +++ b/www/apps/book/app/advanced-development/api-routes/responses/page.mdx @@ -17,14 +17,14 @@ export const jsonHighlights = [ ] ```ts title="src/api/store/custom/route.ts" highlights={jsonHighlights} apiTesting testApiUrl="http://localhost:9000/store/custom" testApiMethod="GET" -import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"; +import { MedusaRequest, MedusaResponse } from "@medusajs/medusa" export const GET = async ( req: MedusaRequest, res: MedusaResponse ) => { res.json({ - message: "Hello, World!" + message: "Hello, World!", }) } ``` @@ -52,14 +52,14 @@ export const statusHighlight = [ ] ```ts title="src/api/store/custom/route.ts" highlights={statusHighlight} apiTesting testApiUrl="http://localhost:9000/store/custom" testApiMethod="GET" -import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"; +import { MedusaRequest, MedusaResponse } from "@medusajs/medusa" export const GET = async ( req: MedusaRequest, res: MedusaResponse ) => { res.status(201).json({ - message: "Hello, World!" + message: "Hello, World!", }) } ``` @@ -84,7 +84,7 @@ export const streamHighlights = [ ] ```ts highlights={streamHighlights} -import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"; +import { MedusaRequest, MedusaResponse } from "@medusajs/medusa" export const GET = async ( req: MedusaRequest, diff --git a/www/apps/book/app/advanced-development/api-routes/validation/page.mdx b/www/apps/book/app/advanced-development/api-routes/validation/page.mdx index 11f681a255..e4b76188db 100644 --- a/www/apps/book/app/advanced-development/api-routes/validation/page.mdx +++ b/www/apps/book/app/advanced-development/api-routes/validation/page.mdx @@ -27,7 +27,7 @@ import { z } from "zod" export const PostStoreCustomSchema = z.object({ a: z.number(), - b: z.number() + b: z.number(), }) ``` @@ -48,7 +48,7 @@ For example, create the file `src/api/middlewares.ts` with the following content ```ts title="src/api/middlewares.ts" import { defineMiddlewares } from "@medusajs/medusa" import { - validateAndTransformBody + validateAndTransformBody, } from "@medusajs/medusa/dist/api/utils/validate-body" import { PostStoreCustomSchema } from "./store/custom/validators" @@ -58,7 +58,7 @@ export default defineMiddlewares({ matcher: "/store/custom", method: "POST", middlewares: [ - validateAndTransformBody(PostStoreCustomSchema) + validateAndTransformBody(PostStoreCustomSchema), ], }, ], @@ -87,9 +87,9 @@ export const routeHighlights = [ ] ```ts title="src/api/store/custom/route.ts" highlights={routeHighlights} -import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"; +import { MedusaRequest, MedusaResponse } from "@medusajs/medusa" import { z } from "zod" -import { PostStoreCustomSchema } from "./validators"; +import { PostStoreCustomSchema } from "./validators" type PostStoreCustomSchemaType = z.infer< typeof PostStoreCustomSchema @@ -100,7 +100,7 @@ export const POST = async ( res: MedusaResponse ) => { res.json({ - sum: req.validatedBody.a + req.validatedBody.b + sum: req.validatedBody.a + req.validatedBody.b, }) } ``` diff --git a/www/apps/book/app/advanced-development/data-models/manage-relationships/page.mdx b/www/apps/book/app/advanced-development/data-models/manage-relationships/page.mdx index ea14fee313..e0004e7f29 100644 --- a/www/apps/book/app/advanced-development/data-models/manage-relationships/page.mdx +++ b/www/apps/book/app/advanced-development/data-models/manage-relationships/page.mdx @@ -84,7 +84,7 @@ export const retrieveHighlights = [ const product = await helloModuleService.retrieveProduct( "123", { - relations: ["orders"] + relations: ["orders"], } ) ``` diff --git a/www/apps/book/app/advanced-development/events-and-subscribers/emit-event/page.mdx b/www/apps/book/app/advanced-development/events-and-subscribers/emit-event/page.mdx index 198aa3b37b..f14ea2bc10 100644 --- a/www/apps/book/app/advanced-development/events-and-subscribers/emit-event/page.mdx +++ b/www/apps/book/app/advanced-development/events-and-subscribers/emit-event/page.mdx @@ -22,10 +22,10 @@ export const highlights = [ ```ts highlights={highlights} import { - createWorkflow + createWorkflow, } from "@medusajs/workflows-sdk" import { - emitEventStep + emitEventStep, } from "@medusajs/core-flows" const helloWorldWorkflow = createWorkflow( @@ -36,8 +36,8 @@ const helloWorldWorkflow = createWorkflow( emitEventStep({ eventName: "custom.created", data: { - id: "123" - } + id: "123", + }, }) } ) diff --git a/www/apps/book/app/advanced-development/modules/query/page.mdx b/www/apps/book/app/advanced-development/modules/query/page.mdx new file mode 100644 index 0000000000..291f798342 --- /dev/null +++ b/www/apps/book/app/advanced-development/modules/query/page.mdx @@ -0,0 +1,237 @@ +import { TypeList, Tabs, TabsList, TabsTriggerVertical, TabsContent, TabsContentWrapper } from "docs-ui" + +export const metadata = { + title: `${pageNumber} Query`, +} + +# {metadata.title} + +In this chapter, you’ll learn about the Query utility and how to use it to fetch data from modules. + + + +Remote Query is now deprecated in favor of Query. Follow this documentation to see the difference in the usage. + + + +## What is Query? + +Query fetches data across modules. It’s a set of methods registered in the Medusa container under the `query` key. + +In your resources, such as API routes or workflows, you can resolve Query to fetch data across custom modules and Medusa’s commerce modules. + +--- + +## Query Example + +For example, create the route `src/api/store/query/route.ts` with the following content: + +export const exampleHighlights = [ + ["13", "", "Resolve Query from the Medusa container."], + ["15", "graph", "Run a query to retrieve data."], + ["16", "entryPoint", "The name of the data model you're querying."], + ["17", "fields", "An array of the data model’s properties to retrieve in the result."], +] + +```ts title="src/api/store/query/route.ts" highlights={exampleHighlights} apiTesting testApiMethod="GET" testApiUrl="http://localhost:9000/store/query" collapsibleLines="1-8" expandButtonLabel="Show Imports" +import { + MedusaRequest, + MedusaResponse, +} from "@medusajs/medusa" +import { + ContainerRegistrationKeys, +} from "@medusajs/utils" + +export const GET = async ( + req: MedusaRequest, + res: MedusaResponse +) => { + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) + + const { data: myCustoms } = await query.graph({ + entryPoint: "my_custom", + fields: ["id", "name"], + }) + + res.json({ my_customs: myCustoms }) +} +``` + +In the above example, you resolve Query from the Medusa container using the `ContainerRegistrationKeys.QUERY` (`query`) key. + +Then, you run a query using its `graph` method. This method 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. + +The method returns an object that has a `data` property, which holds an array of the retrieved data. For example: + +```json title="Returned Data" +{ + "data": [ + { + "id": "123", + "name": "test" + } + ] +} +``` + +--- + +## 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 { data: myCustoms } = await query.graph({ + 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 { data: myCustoms } = await query.graph({ + entryPoint: "my_custom", + fields: [ + "id", + "name", + "products.*", + ], +}) +``` + +--- + +## Apply Filters + +```ts highlights={[["6"], ["7"], ["8"], ["9"]]} +const { data: myCustoms } = await query.graph({ + entryPoint: "my_custom", + fields: ["id", "name"], + variables: { + filters: { + id: [ + "mc_01HWSVWR4D2XVPQ06DQ8X9K7AX", + "mc_01HWSVWK3KYHKQEE6QGS2JC3FX", + ], + }, + }, +}) +``` + + + +Filters don't apply on fields of linked data models from other modules. + + + +The `query.graph` function accepts a `variables` property. You can use this property to filter retrieved records. + + + +--- + +## Sort Records + +```ts highlights={[["5"], ["6"], ["7"]]} +const { data: myCustoms } = await query.graph({ + entryPoint: "my_custom", + fields: ["id", "name"], + variables: { + order: { + name: "DESC", + }, + }, +}) +``` + + + +Sorting doesn't work on fields of linked data models from other modules. + + + +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={[["8", "skip", "The number of records to skip before fetching the results."], ["9", "take", "The number of records to fetch."]]} +const { + data: myCustoms, + metadata: { count, take, skip }, +} = await query.graph({ + entryPoint: "my_custom", + fields: ["id", "name"], + variables: { + skip: 0, + take: 10, + }, +}) +``` + +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 you provide the pagination fields, the `query.graph` method's returned object has a `metadata` property. Its value is an object having the following properties: + + diff --git a/www/apps/book/app/advanced-development/modules/remote-query/page.mdx b/www/apps/book/app/advanced-development/modules/remote-query/page.mdx deleted file mode 100644 index 0daf58a54e..0000000000 --- a/www/apps/book/app/advanced-development/modules/remote-query/page.mdx +++ /dev/null @@ -1,410 +0,0 @@ -import { TypeList, Tabs, TabsList, TabsTriggerVertical, 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. - ---- - -## 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: - - - - - - diff --git a/www/apps/book/app/advanced-development/workflows/workflow-hooks/page.mdx b/www/apps/book/app/advanced-development/workflows/workflow-hooks/page.mdx index 4911da8fac..1e06ecde71 100644 --- a/www/apps/book/app/advanced-development/workflows/workflow-hooks/page.mdx +++ b/www/apps/book/app/advanced-development/workflows/workflow-hooks/page.mdx @@ -94,7 +94,7 @@ This property is an object that holds additional data passed to the workflow. To pass that additional data when executing the workflow, pass it as a parameter to the `.run` method of the workflow: ```ts highlights={[["10", "additional_data"]]} -import type { MedusaRequest, MedusaResponse } from "@medusajs/medusa"; +import type { MedusaRequest, MedusaResponse } from "@medusajs/medusa" import { createProductsWorkflow } from "@medusajs/core-flows" export async function POST(req: MedusaRequest, res: MedusaResponse) { @@ -104,8 +104,8 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) { // ... ], additional_data: { - custom_field: "test" - } + custom_field: "test", + }, }, }) } diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx index 1dd095a969..e02486f7e6 100644 --- a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx +++ b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx @@ -29,7 +29,7 @@ export async function GET( res: MedusaResponse ){ res.json({ - message: "Hello, World!" + message: "Hello, World!", }) } ``` @@ -58,7 +58,7 @@ medusaIntegrationTestRunner({ }) }) }) - } + }, }) ``` @@ -107,7 +107,7 @@ And consider that the file `src/api/store/custom/route.ts` defines another route ```ts title="src/api/store/custom/route.ts" // other imports... -import HelloModuleService from "../../../modules/hello/service"; +import HelloModuleService from "../../../modules/hello/service" // ... @@ -124,7 +124,7 @@ export async function POST( ) res.json({ - my_custom: myCustom + my_custom: myCustom, }) } ``` @@ -155,7 +155,7 @@ medusaIntegrationTestRunner({ `/store/custom`, { id, - name: "Test" + name: "Test", } ) @@ -170,7 +170,7 @@ medusaIntegrationTestRunner({ }) }) }) - } + }, }) ``` @@ -210,7 +210,7 @@ medusaIntegrationTestRunner({ }) }) }) - } + }, }) ``` @@ -223,8 +223,8 @@ The `afterAll` hook resolves the `HelloModuleService` and use its `deleteMyCusto Consider a `/store/custom/:id` API route created at `src/api/store/custom/[id]/route.ts`: ```ts title="src/api/store/custom/[id]/route.ts" -import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"; -import HelloModuleService from "../../../modules/hello/service"; +import { MedusaRequest, MedusaResponse } from "@medusajs/medusa" +import HelloModuleService from "../../../modules/hello/service" export async function DELETE( req: MedusaRequest, @@ -237,7 +237,7 @@ export async function DELETE( await helloModuleService.deleteMyCustoms(req.params.id) res.json({ - success: true + success: true, }) } ``` @@ -266,7 +266,7 @@ medusaIntegrationTestRunner({ await helloModuleService.createMyCustoms({ id, - name: "Test" + name: "Test", }) }) @@ -281,7 +281,7 @@ medusaIntegrationTestRunner({ }) }) }) - } + }, }) ``` diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/page.mdx index ecfdd62559..681d272cd3 100644 --- a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/page.mdx +++ b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/page.mdx @@ -34,7 +34,7 @@ import { medusaIntegrationTestRunner } from "medusa-test-utils" medusaIntegrationTestRunner({ testSuite: ({ api, getContainer }) => { // TODO write tests... - } + }, }) ``` diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx index 2b41dff11c..c2da893cf8 100644 --- a/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx +++ b/www/apps/book/app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx @@ -26,7 +26,7 @@ import { createWorkflow, createStep, StepResponse, - WorkflowResponse + WorkflowResponse, } from "@medusajs/workflows-sdk" const step1 = createStep("step-1", () => { @@ -59,7 +59,7 @@ medusaIntegrationTestRunner({ expect(result).toEqual("Hello, World!") }) }) - } + }, }) ``` diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx index 87a5b7791d..2d1e286530 100644 --- a/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx +++ b/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx @@ -56,7 +56,7 @@ moduleIntegrationTestRunner({ expect(message).toEqual("Hello, World!") }) }) - } + }, }) ``` diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/page.mdx index d8a4098b9a..7b657aba35 100644 --- a/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/page.mdx +++ b/www/apps/book/app/debugging-and-testing/testing-tools/modules-tests/page.mdx @@ -35,7 +35,7 @@ moduleIntegrationTestRunner({ resolve: "./modules/hello", testSuite: ({ service }) => { // TODO write tests - } + }, }) ``` @@ -88,7 +88,7 @@ import HelloModuleService from "../service" moduleIntegrationTestRunner({ moduleOptions: { - apiKey: "123" + apiKey: "123", }, // ... }) @@ -108,7 +108,7 @@ import HelloModuleService from "../service" import { model } from "@medusajs/utils" const DummyModel = model.define("dummy_model", { - id: model.id().primaryKey() + id: model.id().primaryKey(), }) moduleIntegrationTestRunner({ diff --git a/www/apps/book/app/debugging-and-testing/testing-tools/page.mdx b/www/apps/book/app/debugging-and-testing/testing-tools/page.mdx index 05734cf20a..f28af7be52 100644 --- a/www/apps/book/app/debugging-and-testing/testing-tools/page.mdx +++ b/www/apps/book/app/debugging-and-testing/testing-tools/page.mdx @@ -41,8 +41,8 @@ npm install --save-dev jest @types/jest @swc/jest Then, create the file `jest.config.js` with the following content: ```js title="jest.config.js" -const { loadEnv } = require('@medusajs/utils') -loadEnv('test', process.cwd()) +const { loadEnv } = require("@medusajs/utils") +loadEnv("test", process.cwd()) module.exports = { transform: { diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index 9d840c3d8b..c987045e93 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -6,7 +6,7 @@ export const generatedEditDates = { "app/basics/modules-and-services/page.mdx": "2024-09-03T07:45:28.079Z", "app/basics/commerce-modules/page.mdx": "2024-09-03T07:48:48.148Z", "app/advanced-development/workflows/retry-failed-steps/page.mdx": "2024-07-31T17:01:33+03:00", - "app/advanced-development/workflows/workflow-hooks/page.mdx": "2024-08-13T09:55:37+03:00", + "app/advanced-development/workflows/workflow-hooks/page.mdx": "2024-09-10T11:39:51.168Z", "app/cheatsheet/page.mdx": "2024-07-11T13:53:40+03:00", "app/debugging-and-testing/logging/page.mdx": "2024-07-04T17:26:03+03:00", "app/more-resources/page.mdx": "2024-07-04T17:26:03+03:00", @@ -33,19 +33,19 @@ export const generatedEditDates = { "app/advanced-development/admin/widgets/page.mdx": "2024-08-06T09:44:22+02:00", "app/advanced-development/data-models/page.mdx": "2024-07-04T17:26:03+03:00", "app/advanced-development/modules/remote-link/page.mdx": "2024-07-24T09:16:01+02:00", - "app/advanced-development/api-routes/protected-routes/page.mdx": "2024-09-04T10:11:25.860Z", + "app/advanced-development/api-routes/protected-routes/page.mdx": "2024-09-10T11:39:51.166Z", "app/advanced-development/workflows/add-workflow-hook/page.mdx": "2024-08-13T09:55:37+03:00", "app/advanced-development/events-and-subscribers/data-payload/page.mdx": "2024-07-16T17:12:05+01:00", "app/advanced-development/data-models/default-properties/page.mdx": "2024-07-02T12:34:44+03:00", "app/advanced-development/workflows/advanced-example/page.mdx": "2024-07-31T17:01:33+03:00", - "app/advanced-development/events-and-subscribers/emit-event/page.mdx": "2024-08-05T11:39:47+03:00", + "app/advanced-development/events-and-subscribers/emit-event/page.mdx": "2024-09-10T11:39:51.168Z", "app/advanced-development/workflows/conditions/page.mdx": "2024-07-31T17:01:33+03:00", "app/advanced-development/modules/module-link-directions/page.mdx": "2024-07-24T09:16:01+02:00", "app/advanced-development/admin/page.mdx": "2024-05-29T13:50:19+03:00", "app/advanced-development/workflows/long-running-workflow/page.mdx": "2024-07-31T17:01:33+03:00", "app/advanced-development/workflows/constructor-constraints/page.mdx": "2024-07-17T13:19:51+01:00", "app/advanced-development/data-models/write-migration/page.mdx": "2024-07-15T17:46:10+02:00", - "app/advanced-development/data-models/manage-relationships/page.mdx": "2024-08-15T16:30:00+03:00", + "app/advanced-development/data-models/manage-relationships/page.mdx": "2024-09-10T11:39:51.167Z", "app/advanced-development/modules/remote-query/page.mdx": "2024-07-21T21:20:24+02:00", "app/advanced-development/modules/options/page.mdx": "2024-08-05T07:23:49+00:00", "app/advanced-development/data-models/relationships/page.mdx": "2024-08-15T16:30:00+03:00", @@ -57,7 +57,7 @@ export const generatedEditDates = { "app/advanced-development/scheduled-jobs/execution-number/page.mdx": "2024-07-02T09:41:15+00:00", "app/advanced-development/api-routes/parameters/page.mdx": "2024-09-04T08:17:50.071Z", "app/advanced-development/api-routes/http-methods/page.mdx": "2024-09-04T08:15:11.609Z", - "app/advanced-development/admin/tips/page.mdx": "2024-08-05T13:20:34+03:00", + "app/advanced-development/admin/tips/page.mdx": "2024-09-10T11:39:51.165Z", "app/advanced-development/api-routes/cors/page.mdx": "2024-09-04T08:24:47.068Z", "app/advanced-development/admin/ui-routes/page.mdx": "2024-08-06T09:44:22+02:00", "app/advanced-development/api-routes/middlewares/page.mdx": "2024-09-04T09:45:12.441Z", @@ -66,14 +66,18 @@ export const generatedEditDates = { "app/advanced-development/data-models/index/page.mdx": "2024-07-04T17:26:03+03:00", "app/advanced-development/custom-cli-scripts/page.mdx": "2024-07-04T17:26:03+03:00", "app/advanced-development/data-models/property-types/page.mdx": "2024-07-04T17:26:03+03:00", - "app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2024-09-02T10:57:08.040Z", - "app/debugging-and-testing/testing-tools/integration-tests/page.mdx": "2024-09-02T10:56:09.872Z", - "app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2024-09-02T10:57:04.202Z", - "app/debugging-and-testing/testing-tools/page.mdx": "2024-09-02T10:08:29.388Z", + "app/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2024-09-10T11:39:51.170Z", + "app/debugging-and-testing/testing-tools/integration-tests/page.mdx": "2024-09-10T11:39:51.170Z", + "app/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2024-09-10T11:39:51.171Z", + "app/debugging-and-testing/testing-tools/page.mdx": "2024-09-10T11:39:51.172Z", "app/debugging-and-testing/testing-tools/unit-tests/module-example/page.mdx": "2024-09-02T11:04:27.232Z", "app/debugging-and-testing/testing-tools/unit-tests/page.mdx": "2024-09-02T11:03:26.997Z", "app/advanced-development/api-routes/page.mdx": "2024-09-04T09:36:33.961Z", - "app/advanced-development/api-routes/responses/page.mdx": "2024-09-04T09:40:38.986Z", - "app/advanced-development/api-routes/validation/page.mdx": "2024-09-04T09:50:52.129Z", - "app/advanced-development/api-routes/errors/page.mdx": "2024-09-04T11:03:55.017Z" + "app/advanced-development/api-routes/responses/page.mdx": "2024-09-10T11:39:51.167Z", + "app/advanced-development/api-routes/validation/page.mdx": "2024-09-10T11:39:51.167Z", + "app/advanced-development/api-routes/errors/page.mdx": "2024-09-10T11:39:51.166Z", + "app/advanced-development/admin/constraints/page.mdx": "2024-09-10T11:39:51.165Z", + "app/advanced-development/modules/query/page.mdx": "2024-09-10T11:39:51.168Z", + "app/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx": "2024-09-10T11:39:51.171Z", + "app/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2024-09-10T11:39:51.171Z" } \ No newline at end of file diff --git a/www/apps/book/next.config.mjs b/www/apps/book/next.config.mjs index 641cbd7b56..61feec7f79 100644 --- a/www/apps/book/next.config.mjs +++ b/www/apps/book/next.config.mjs @@ -127,6 +127,15 @@ const nextConfig = { ], } }, + async redirects() { + return [ + { + source: "/advanced-development/modules/remote-query", + destination: "/advanced-development/modules/query", + permanent: true, + }, + ] + }, } export default withMDX(nextConfig) diff --git a/www/apps/book/sidebar.mjs b/www/apps/book/sidebar.mjs index f005627a91..a5bb1f7e30 100644 --- a/www/apps/book/sidebar.mjs +++ b/www/apps/book/sidebar.mjs @@ -172,8 +172,8 @@ export const sidebar = numberSidebarItems( }, { type: "link", - path: "/advanced-development/modules/remote-query", - title: "Remote Query", + path: "/advanced-development/modules/query", + title: "Query", }, { type: "link", diff --git a/www/apps/resources/app/commerce-modules/product/guides/price-with-taxes/page.mdx b/www/apps/resources/app/commerce-modules/product/guides/price-with-taxes/page.mdx index 7d9298ad5c..cb009e79d9 100644 --- a/www/apps/resources/app/commerce-modules/product/guides/price-with-taxes/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/guides/price-with-taxes/page.mdx @@ -14,17 +14,18 @@ In this document, you'll learn how to calculate a product variant's price with t You'll need the following resources for the taxes calculation: -1. Remote query to retrieve the product's variants' prices for a context. Learn more about that in [this guide](../price/page.mdx). +1. Query to retrieve the product's variants' prices for a context. Learn more about that in [this guide](../price/page.mdx). 2. The Tax Module's main service to get the tax lines for each product. ```ts // other imports... import { ModuleRegistrationName, + ContainerRegistrationKeys, } from "@medusajs/utils" // In an API route, workflow step, etc... -const remoteQuery = container.resolve("remoteQuery") +const query = container.resolve(ContainerRegistrationKeys.QUERY) const taxModuleService = container.resolve( ModuleRegistrationName.TAX ) @@ -34,16 +35,10 @@ const taxModuleService = container.resolve( ## Step 1: Retrieve Prices for a Context -After resolving the resources, use the remote query to retrieve the products with the variants' prices for a context: +After resolving the resources, use Query to retrieve the products with the variants' prices for a context: ```ts -// other imports... -import { - remoteQueryObjectFromString, -} from "@medusajs/utils" - -// ... -const query = remoteQueryObjectFromString({ +const { data: products } = await query.graph({ entryPoint: "product", fields: [ "*", @@ -52,18 +47,16 @@ const query = remoteQueryObjectFromString({ ], variables: { filters: { - id, + id: "prod_123", }, "variants.calculated_price": { context: { - region_id, - currency_code, + region_id: "region_123", + currency_code: "usd", }, }, }, }) - -const products = await remoteQuery(query) ``` diff --git a/www/apps/resources/app/commerce-modules/product/guides/price/page.mdx b/www/apps/resources/app/commerce-modules/product/guides/price/page.mdx index 45ce4d0050..40ae204e1f 100644 --- a/www/apps/resources/app/commerce-modules/product/guides/price/page.mdx +++ b/www/apps/resources/app/commerce-modules/product/guides/price/page.mdx @@ -3,29 +3,29 @@ sidebar_label: "Get Product Variant Prices" --- export const metadata = { - title: `Get Product Variant Prices using Remote Query`, + title: `Get Product Variant Prices using Query`, } # {metadata.title} -In this document, you'll learn how to retrieve product variant prices in the Medusa application using the [remote query](!docs!/advanced-development/modules/remote-query). +In this document, you'll learn how to retrieve product variant prices in the Medusa application using the [Query](!docs!/advanced-development/modules/query). - + The Product Module doesn't provide pricing functionalities. The Medusa application links the Product Module's `ProductVariant` data model to the Pricing Module's `PriceSet` data model. -So, to retrieve data across the linked records of the two modules, you use the remote query. +So, to retrieve data across the linked records of the two modules, you use Query. ## Retrieve All Product Variant Prices -To retrieve all product variant prices, retrieve the product using the remote query and include among its fields `variants.prices.*`. +To retrieve all product variant prices, retrieve the product using Query and include among its fields `variants.prices.*`. For example: ```ts highlights={[["6"]]} -const query = remoteQueryObjectFromString({ +const { data: products } = await query.graph({ entryPoint: "product", fields: [ "*", @@ -40,9 +40,6 @@ const query = remoteQueryObjectFromString({ }, }, }) - -// `result` is array of products -const result = await remoteQuery(query) ``` Each variant in the retrieved products has a `prices` array property with all the product variant prices. Each price object has the properties of the [Pricing Module's Price data model](/references/pricing/models/Price). @@ -59,7 +56,7 @@ Learn more about prices calculation in [this Pricing Module documentation](../.. -To retrieve calculated prices of variants based on a context, retrieve the products using remote query and: +To retrieve calculated prices of variants based on a context, retrieve the products using Query and: - Pass `variants.calculated_price.*` in the `fields` property. - Pass in the `variables` property a `variants.calculated_price` property whose value is the [calculation context object](../../../pricing/price-calculation/page.mdx#calculation-context). @@ -67,7 +64,7 @@ To retrieve calculated prices of variants based on a context, retrieve the produ For example: ```ts highlights={[["6"], ["12"], ["13"], ["14"], ["15"], ["16"], ["17"]]} -const query = remoteQueryObjectFromString({ +const { data: products } = await query.graph({ entryPoint: "product", fields: [ "*", @@ -76,7 +73,7 @@ const query = remoteQueryObjectFromString({ ], variables: { filters: { - id, + id: "prod_123", }, "variants.calculated_price": { context: { @@ -86,9 +83,6 @@ const query = remoteQueryObjectFromString({ }, }, }) - -// `result` is array of products -const result = await remoteQuery(query) ``` The `variants.calculated_price` property of `variables` is an object that has a `context` property. `context`'s value is an object whose keys are price rules, such as `region_id`, and value is the rule's value in this context, such as the customer's region's ID. diff --git a/www/apps/resources/app/medusa-container-resources/page.mdx b/www/apps/resources/app/medusa-container-resources/page.mdx index 3509f1043f..eb13243174 100644 --- a/www/apps/resources/app/medusa-container-resources/page.mdx +++ b/www/apps/resources/app/medusa-container-resources/page.mdx @@ -8,6 +8,12 @@ export const metadata = { This documentation page includes the list of resources registered in the Medusa container of your Medusa application. + + +Use the `ContainerRegistrationKeys` enum imported from `@medusajs/utils` to resolve these resources' names. + + + @@ -43,7 +49,7 @@ This documentation page includes the list of resources registered in the Medusa - `configModule` + `configModule` or `ContainerRegistrationKeys.CONFIG_MODULE` @@ -61,7 +67,7 @@ This documentation page includes the list of resources registered in the Medusa - `logger` + `logger` or `ContainerRegistrationKeys.LOGGER` @@ -69,17 +75,17 @@ This documentation page includes the list of resources registered in the Medusa - Remote Query + Query - The remote query function. + The Query utility methods. - `remoteQuery` + `query` or `ContainerRegistrationKeys.QUERY` @@ -97,7 +103,7 @@ This documentation page includes the list of resources registered in the Medusa - `remoteLink` + `remoteLink` or `ContainerRegistrationKeys.REMOTE_LINK` diff --git a/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx b/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx index 0e69d7204f..5111c5e99d 100644 --- a/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx +++ b/www/apps/resources/app/recipes/digital-products/examples/standard/page.mdx @@ -288,7 +288,7 @@ import { AuthenticatedMedusaRequest, MedusaResponse, } from "@medusajs/medusa" -import { remoteQueryObjectFromString } from "@medusajs/utils" +import { ContainerRegistrationKeys } from "@medusajs/utils" export const GET = async ( req: AuthenticatedMedusaRequest, @@ -299,9 +299,12 @@ export const GET = async ( limit = 20, offset = 0, } = req.validatedQuery || {} - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) - const query = remoteQueryObjectFromString({ + const { + data: digitalProducts, + metadata: { count, take, skip }, + } = await query.graph({ entryPoint: "digital_product", fields: [ "*", @@ -315,13 +318,8 @@ export const GET = async ( }, }) - const { - rows, - metadata: { count, take, skip }, - } = await remoteQuery(query) - res.json({ - digital_products: rows, + digital_products: digitalProducts, count, limit: take, offset: skip, @@ -331,7 +329,7 @@ export const GET = async ( This adds a `GET` API route at `/admin/digital-products`. -In the route handler, you use the remote query to retrieve the list of digital products and their relations. The route handler also supports pagination. +In the route handler, you use Query to retrieve the list of digital products and their relations. The route handler also supports pagination. ### Test API Route @@ -364,7 +362,7 @@ Make sure to replace `{token}` with the JWT token you retrieved. ### Further Reads - [How to Create an API Route](!docs!/basics/api-routes) -- [Learn more about the remote query](!docs!/advanced-development/modules/remote-query) +- [Learn more about Query](!docs!/advanced-development/modules/query) --- @@ -1830,7 +1828,7 @@ Create the file `digital-product/src/subscribers/handle-digital-order.ts` with t export const subscriberHighlight = [ ["20", "notificationModuleService", "Resolve the Notification Module's service to use it later to send a notification."], ["22", "fileModuleService", "Resolve the File Module's service to use it later to retrieve a media's URL."], - ["26", "query", "Assemble the query to retrieve the digital product order."] + ["26", "query", "Run the query to retrieve the digital product order."] ] ```ts title="digital-product/src/subscribers/handle-digital-order.ts" highlights={subscriberHighlight} collapsibleLines="1-14" expandMoreLabel="Show Imports" @@ -1844,7 +1842,7 @@ import { } from "@medusajs/types" import { ModuleRegistrationName, - remoteQueryObjectFromString, + ContainerRegistrationKeys, } from "@medusajs/utils" import { MediaType } from "../modules/digital-product/types" @@ -1852,14 +1850,14 @@ async function digitalProductOrderCreatedHandler({ event: { data }, container, }: SubscriberArgs<{ id: string }>) { - const remoteQuery = container.resolve("remoteQuery") + const query = container.resolve(ContainerRegistrationKeys.QUERY) const notificationModuleService: INotificationModuleService = container .resolve(ModuleRegistrationName.NOTIFICATION) const fileModuleService: IFileModuleService = container.resolve( ModuleRegistrationName.FILE ) - const query = remoteQueryObjectFromString({ + const { data: [digitalProductOrder] } = await query.graph({ entryPoint: "digital_product_order", fields: [ "*", @@ -1874,8 +1872,6 @@ async function digitalProductOrderCreatedHandler({ }, }) - const digitalProductOrder = (await remoteQuery(query))[0] - // TODO format and send notification } @@ -2031,7 +2027,7 @@ You return in the response the preview files. Create the file `src/api/store/customers/me/digital-products/route.ts` with the following content: export const purchasedDpHighlights = [ - ["15", "remoteQueryObjectFromString", "Retrieve the customer's purchased digital products."] + ["15", "graph", "Retrieve the customer's purchased digital products."] ] ```ts title="src/api/store/customers/me/digital-products/route.ts" highlights={purchasedDpHighlights} collapsibleLines="1-8" expandMoreLabel="Show Imports" @@ -2040,16 +2036,16 @@ import { MedusaResponse, } from "@medusajs/medusa" import { - remoteQueryObjectFromString, + ContainerRegistrationKeys, } from "@medusajs/utils" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) - const query = remoteQueryObjectFromString({ + const { data: [customer] } = await query.graph({ entryPoint: "customer", fields: [ "orders.digital_product_order.products.*", @@ -2062,11 +2058,9 @@ export const GET = async ( }, }) - const result = await remoteQuery(query) - const digitalProducts = {} - result[0].orders.forEach((order) => { + customer.orders.forEach((order) => { order.digital_product_order.products.forEach((product) => { digitalProducts[product.id] = product }) @@ -2076,23 +2070,22 @@ export const GET = async ( digital_products: Object.values(digitalProducts), }) } - ``` This adds a `GET` API route at `/store/customers/me/digital-products`. All API routes under `/store/customers/me` require customer authentication. -In the route handler, you use remote query to retrieve the customer’s orders and linked digital product orders, and return the purchased digital products in the response. +In the route handler, you use Query to retrieve the customer’s orders and linked digital product orders, and return the purchased digital products in the response. ### Get Digital Product Media Download URL API Route Create the file `src/api/store/customers/me/digital-products/[mediaId]/download/route.ts` with the following content: export const downloadUrlHighlights = [ - ["20", "remoteQueryObjectFromString", "Get the customer's orders and linked digital orders."], - ["37", "remoteQueryObjectFromString", "Get the digital product orders of the customer and associated products and media."], - ["62", "foundMedia", "Set `foundMedia` if the media's ID is equal to the ID passed as a route parameter."], - ["68", "!foundMedia", "If `foundMedia` isn't set, throw an error."], - ["75", "retrieveFile", "Retrieve the details of the media's file."] + ["20", "query.graph", "Get the customer's orders and linked digital orders."], + ["36", "query.graph", "Get the digital product orders of the customer and associated products and media."], + ["56", "foundMedia", "Set `foundMedia` if the media's ID is equal to the ID passed as a route parameter."], + ["65", "!foundMedia", "If `foundMedia` isn't set, throw an error."], + ["72", "retrieveFile", "Retrieve the details of the media's file."] ] ```ts title="src/api/store/customers/me/digital-products/[mediaId]/download/route.ts" highlights={downloadUrlHighlights} collapsibleLines="1-10" expandMoreLabel="Show Imports" @@ -2102,7 +2095,7 @@ import { } from "@medusajs/medusa" import { ModuleRegistrationName, - remoteQueryObjectFromString, + ContainerRegistrationKeys, MedusaError, } from "@medusajs/utils" @@ -2113,9 +2106,9 @@ export const POST = async ( const fileModuleService = req.scope.resolve( ModuleRegistrationName.FILE ) - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) - const customerQuery = remoteQueryObjectFromString({ + const { data: [customer] } = await query.graph({ entryPoint: "customer", fields: [ "orders.digital_product_order.*", @@ -2127,12 +2120,11 @@ export const POST = async ( }, }) - const customerResult = await remoteQuery(customerQuery) - const customerDigitalOrderIds = customerResult[0].orders + const customerDigitalOrderIds = customer.orders .filter((order) => order.digital_product_order !== undefined) .map((order) => order.digital_product_order.id) - const dpoQuery = remoteQueryObjectFromString({ + const { data: dpoResult } = await query.graph({ entryPoint: "digital_product_order", fields: [ "products.medias.*", @@ -2144,8 +2136,6 @@ export const POST = async ( }, }) - const dpoResult = await remoteQuery(dpoQuery) - if (!dpoResult.length) { throw new MedusaError( MedusaError.Types.NOT_ALLOWED, diff --git a/www/apps/resources/app/recipes/digital-products/page.mdx b/www/apps/resources/app/recipes/digital-products/page.mdx index 760e370bae..a888929558 100644 --- a/www/apps/resources/app/recipes/digital-products/page.mdx +++ b/www/apps/resources/app/recipes/digital-products/page.mdx @@ -123,9 +123,9 @@ Create workflows to implement these flows, then utilize these workflows in other ## Manage Linked Records -If you've defined links between data models of two modules, you can manage them through two functions: remote link and remote query. +If you've defined links between data models of two modules, you can manage them through two functions: remote link and Query. -Use the remote link to create a link between two records, and use the remote query to fetch data across linked data models. +Use the remote link to create a link between two records, and use Query to fetch data across linked data models. diff --git a/www/apps/resources/app/recipes/marketplace/examples/restaurant-delivery/page.mdx b/www/apps/resources/app/recipes/marketplace/examples/restaurant-delivery/page.mdx index f1f1e9232f..b28cfde8de 100644 --- a/www/apps/resources/app/recipes/marketplace/examples/restaurant-delivery/page.mdx +++ b/www/apps/resources/app/recipes/marketplace/examples/restaurant-delivery/page.mdx @@ -627,16 +627,16 @@ In the file `src/api/restaurants/route.ts` add the following API route: ```ts title="src/api/restaurants/route.ts" // other imports... import { MedusaRequest, MedusaResponse } from "@medusajs/medusa" -import { remoteQueryObjectFromString } from "@medusajs/utils" +import { ContainerRegistrationKeys } from "@medusajs/utils" // ... export async function GET(req: MedusaRequest, res: MedusaResponse) { const { currency_code = "eur", ...queryFilters } = req.query - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) - const restaurantsQuery = remoteQueryObjectFromString({ + const { data: restaurants } = await query.graph({ entryPoint: "restaurants", fields: [ "id", @@ -662,13 +662,11 @@ export async function GET(req: MedusaRequest, res: MedusaResponse) { }, }) - const restaurants = await remoteQuery(restaurantsQuery) - return res.status(200).json({ restaurants }) } ``` -This creates a `GET` API route at `/restaurants`. It uses remote query to retrieve a restaurant, its products, and the product variant’s prices for a specified currency. +This creates a `GET` API route at `/restaurants`. It uses Query to retrieve a restaurant, its products, and the product variant’s prices for a specified currency. ### Test it Out @@ -682,7 +680,7 @@ This returns the list of restaurants in the response. ### Further Reads -- [What is Remote Query and how to use it](!docs!/advanced-development/modules/remote-query) +- [What is and how to use it](!docs!/advanced-development/modules/query) - [How to Retrieve Prices for Product Variants](../../../../commerce-modules/product/guides/price/page.mdx) --- @@ -1502,14 +1500,14 @@ Create the file `src/workflows/delivery/steps/notify-restaurant.ts` with the fol export const notifyRestaurantStepHighlights = [ ["11", "async", "Set the step as async."], - ["18", "deliveryQuery", "Retrieve the delivery and its restaurant."], - ["32", "emit", "Emit a custom event that can be used to notify the restaurant that a new delivery is created."] + ["18", "graph", "Retrieve the delivery and its restaurant."], + ["30", "emit", "Emit a custom event that can be used to notify the restaurant that a new delivery is created."] ] ```ts title="src/workflows/delivery/steps/notify-restaurant.ts" highlights={notifyRestaurantStepHighlights} collapsibleLines="1-6" expandButtonLabel="Show Imports" import { ModuleRegistrationName, - remoteQueryObjectFromString, + ContainerRegistrationKeys, } from "@medusajs/utils" import { createStep } from "@medusajs/workflows-sdk" @@ -1522,9 +1520,9 @@ export const notifyRestaurantStep = createStep( maxRetries: 2, }, async function (deliveryId: string, { container }) { - const remoteQuery = container.resolve("remoteQuery") + const query = container.resolve(ContainerRegistrationKeys.QUERY) - const deliveryQuery = remoteQueryObjectFromString({ + const { data: [delivery] } = await query.graph({ entryPoint: "deliveries", variables: { filters: { @@ -1534,8 +1532,6 @@ export const notifyRestaurantStep = createStep( fields: ["id", "restaurant.id"], }) - const delivery = await remoteQuery(deliveryQuery).then((res) => res[0]) - const eventBus = container.resolve(ModuleRegistrationName.EVENT_BUS) await eventBus.emit({ @@ -1547,7 +1543,6 @@ export const notifyRestaurantStep = createStep( }) } ) - ``` In this step, you: @@ -1600,7 +1595,7 @@ import { CreateOrderShippingMethodDTO } from "@medusajs/types" import { ModuleRegistrationName, Modules, - remoteQueryObjectFromString, + ContainerRegistrationKeys, } from "@medusajs/utils" import { StepResponse, createStep } from "@medusajs/workflows-sdk" import { DELIVERY_MODULE } from "../../../modules/delivery" @@ -1608,9 +1603,9 @@ import { DELIVERY_MODULE } from "../../../modules/delivery" export const createOrderStep = createStep( "create-order-step", async function (deliveryId: string, { container }) { - const remoteQuery = container.resolve("remoteQuery") + const query = container.resolve(ContainerRegistrationKeys.QUERY) - const deliveryQuery = remoteQueryObjectFromString({ + const { data: [delivery] } = await query.graph({ entryPoint: "deliveries", variables: { filters: { @@ -1627,8 +1622,6 @@ export const createOrderStep = createStep( ], }) - const delivery = await remoteQuery(deliveryQuery).then((res) => res[0]) - // TODO create order }, async ({ orderId }, { container }) => { @@ -2409,8 +2402,8 @@ Start by creating the file `src/api/utils/is-delivery-restaurant.ts` with the fo export const isDeliveryRestaurantHighlights = [ ["21", "restaurantAdmin", "Retrieve the logged-in restaurant admin."], - ["28", "query", "Retrieve the delivery based on the ID in the path parameter."], - ["42", "", "If the restaurant admin doesn't belong to the delivery's restaurant, return an unauthorized response."] + ["28", "graph", "Retrieve the delivery based on the ID in the path parameter."], + ["40", "", "If the restaurant admin doesn't belong to the delivery's restaurant, return an unauthorized response."] ] ```ts title="src/api/utils/is-delivery-restaurant.ts" highlights={isDeliveryRestaurantHighlights} collapsibleLines="1-10" expandButtonLabel="Show Imports" @@ -2420,7 +2413,7 @@ import { MedusaResponse, } from "@medusajs/medusa" import { - remoteQueryObjectFromString, + ContainerRegistrationKeys, } from "@medusajs/utils" import { RESTAURANT_MODULE } from "../../modules/restaurant" @@ -2429,7 +2422,7 @@ export const isDeliveryRestaurant = async ( res: MedusaResponse, next: MedusaNextFunction ) => { - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) const restaurantModuleService = req.scope.resolve( RESTAURANT_MODULE ) @@ -2441,7 +2434,7 @@ export const isDeliveryRestaurant = async ( } ) - const query = remoteQueryObjectFromString({ + const { data: [delivery] } = await query.graph({ entryPoint: "delivery", fields: [ "restaurant.*", @@ -2453,9 +2446,7 @@ export const isDeliveryRestaurant = async ( }, }) - const result = await remoteQuery(query) - - if (result[0].restaurant.id !== restaurantAdmin.restaurant.id) { + if (delivery.restaurant.id !== restaurantAdmin.restaurant.id) { return res.status(403).json({ message: "unauthorized", }) diff --git a/www/apps/resources/app/recipes/marketplace/examples/vendors/page.mdx b/www/apps/resources/app/recipes/marketplace/examples/vendors/page.mdx index ab76fcae60..de95bade50 100644 --- a/www/apps/resources/app/recipes/marketplace/examples/vendors/page.mdx +++ b/www/apps/resources/app/recipes/marketplace/examples/vendors/page.mdx @@ -563,13 +563,13 @@ To create the API route that retrieves the vendor’s products, create the file export const retrieveProductHighlights = [ ["16", "retrieveVendorAdmin", "Retrive the vendor admin to retrieve its vendor's ID."], - ["33", "remoteQuery", "Retrieve the vendor's products using remote query."] + ["23", "graph", "Retrieve the vendor's products using Query."] ] ```ts title="src/api/vendors/products/route.ts" highlights={retrieveProductHighlights} import { AuthenticatedMedusaRequest, MedusaResponse } from "@medusajs/medusa" import { - remoteQueryObjectFromString, + ContainerRegistrationKeys, } from "@medusajs/utils" import MarketplaceModuleService from "../../../modules/marketplace/service" import { MARKETPLACE_MODULE } from "../../../modules/marketplace" @@ -578,7 +578,7 @@ export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) const marketplaceModuleService: MarketplaceModuleService = req.scope.resolve(MARKETPLACE_MODULE) @@ -589,7 +589,7 @@ export const GET = async ( } ) - const query = remoteQueryObjectFromString({ + const { data: [vendor] } = await query.graph({ entryPoint: "vendor", fields: ["products.*"], variables: { @@ -599,15 +599,13 @@ export const GET = async ( }, }) - const result = await remoteQuery(query) - res.json({ - products: result[0].products, + products: vendor.products, }) } ``` -This adds a `GET` API route at `/vendors/products` that, using the remote query, retrieves the list of products of the vendor and returns them in the response. +This adds a `GET` API route at `/vendors/products` that, using Query, retrieves the list of products of the vendor and returns them in the response. To add the create product API route, add to the same file the following: @@ -782,7 +780,7 @@ curl 'http://localhost:9000/vendors/products' \ ### Further Reads -- [How to use the Remote Query](!docs!/advanced-development/modules/remote-query) +- [How to use Query](!docs!/advanced-development/modules/query) - [How to use the Remote Link](!docs!/advanced-development/modules/remote-link) --- @@ -817,7 +815,7 @@ import { StepResponse, } from "@medusajs/workflows-sdk" import { CartDTO, CartLineItemDTO } from "@medusajs/types" -import { remoteQueryObjectFromString } from "@medusajs/utils" +import { ContainerRegistrationKeys } from "@medusajs/utils" type StepInput = { cart: CartDTO @@ -826,12 +824,12 @@ type StepInput = { const groupVendorItemsStep = createStep( "group-vendor-items", async ({ cart }: StepInput, { container }) => { - const remoteQuery = container.resolve("remoteQuery") + const query = container.resolve(ContainerRegistrationKeys.QUERY) const vendorsItems: Record = {} await Promise.all(cart.items?.map(async (item) => { - const query = remoteQueryObjectFromString({ + const { data: [product] } = await query.graph({ entryPoint: "product", fields: ["vendor.*"], variables: { @@ -841,9 +839,7 @@ const groupVendorItemsStep = createStep( }, }) - const result = await remoteQuery(query) - - const vendorId = result[0].vendor?.id + const vendorId = product.vendor?.id if (!vendorId) { return @@ -1251,13 +1247,13 @@ Create the file `src/api/vendors/orders/route.ts` with the following content: export const getOrderHighlights = [ ["15", "retrieveVendorAdmin", "Retrive the vendor admin to retrieve its vendor's ID."], - ["32", "remoteQuery", "Retrieve the orders of the vendor."], - ["34", "getOrdersListWorkflow", "Use Medusa's workflow to retrieve the list of orders."], + ["22", "graph", "Retrieve the orders of the vendor."], + ["32", "getOrdersListWorkflow", "Use Medusa's workflow to retrieve the list of orders."], ] ```ts title="src/api/vendors/orders/route.ts" highlights={getOrderHighlights} collapsibleLines="1-6" expandMoreLabel="Show Imports" import { AuthenticatedMedusaRequest, MedusaResponse } from "@medusajs/medusa" -import { remoteQueryObjectFromString } from "@medusajs/utils" +import { ContainerRegistrationKeys } from "@medusajs/utils" import { getOrdersListWorkflow } from "@medusajs/core-flows" import MarketplaceModuleService from "../../../modules/marketplace/service" import { MARKETPLACE_MODULE } from "../../../modules/marketplace" @@ -1266,7 +1262,7 @@ export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) const marketplaceModuleService: MarketplaceModuleService = req.scope.resolve(MARKETPLACE_MODULE) @@ -1277,7 +1273,7 @@ export const GET = async ( } ) - const query = remoteQueryObjectFromString({ + const { data: [vendor] } = await query.graph({ entryPoint: "vendor", fields: ["orders.*"], variables: { @@ -1287,8 +1283,6 @@ export const GET = async ( }, }) - const result = await remoteQuery(query) - const { result: orders } = await getOrdersListWorkflow(req.scope) .run({ input: { @@ -1310,7 +1304,7 @@ export const GET = async ( ], variables: { filters: { - id: result[0].orders.map((order) => order.id), + id: vendor.orders.map((order) => order.id), }, }, }, diff --git a/www/apps/resources/app/recipes/subscriptions/examples/standard/page.mdx b/www/apps/resources/app/recipes/subscriptions/examples/standard/page.mdx index 54fc86a73b..caee410da4 100644 --- a/www/apps/resources/app/recipes/subscriptions/examples/standard/page.mdx +++ b/www/apps/resources/app/recipes/subscriptions/examples/standard/page.mdx @@ -654,7 +654,7 @@ In this step, you’ll change what happens when the [Complete Cart API route](!a Create the file `src/api/store/carts/[id]/complete/route.ts` with the following content: export const completeCartHighlights = [ - ["17", "remoteQueryObjectFromString", "Retrieve the cart to retrieve the subscription details from the `metadata`."], + ["17", "graph", "Retrieve the cart to retrieve the subscription details from the `metadata`."], ["31", "", "If the subscription data isn't set in the cart's `metadata`, throw an error"], ["38", "createSubscriptionWorkflow", "Execute the workflow created in the previous step."] ] @@ -665,7 +665,7 @@ import { MedusaResponse, } from "@medusajs/medusa" import { - remoteQueryObjectFromString, + ContainerRegistrationKeys, MedusaError, } from "@medusajs/utils" import createSubscriptionWorkflow from "../../../../../workflows/create-subscription" @@ -674,9 +674,9 @@ export const POST = async ( req: MedusaRequest, res: MedusaResponse ) => { - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) - const query = remoteQueryObjectFromString({ + const { data: [cart] } = await query.graph({ entryPoint: "cart", fields: [ "metadata", @@ -688,7 +688,7 @@ export const POST = async ( }, }) - const { metadata } = (await remoteQuery(query))[0] + const { metadata } = cart if (!metadata?.subscription_interval || !metadata.subscription_period) { throw new MedusaError( @@ -973,7 +973,7 @@ In this step, you’ll add two API routes for admin users: Create the file `src/api/admin/subscriptions/route.ts` with the following content: export const listSubscriptionsAdminHighlight = [ - ["18", "remoteQueryObjectFromString", "Retrieve the subscriptions with their orders and customer."] + ["21", "graph", "Retrieve the subscriptions with their orders and customer."] ] ```ts title="src/api/admin/subscriptions/route.ts" highlights={listSubscriptionsAdminHighlight} @@ -981,20 +981,23 @@ import { AuthenticatedMedusaRequest, MedusaResponse, } from "@medusajs/medusa" -import { remoteQueryObjectFromString } from "@medusajs/utils" +import { ContainerRegistrationKeys } from "@medusajs/utils" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) const { limit = 20, offset = 0, } = req.validatedQuery || {} - const query = remoteQueryObjectFromString({ + const { + data: subscriptions, + metadata: { count, take, skip }, + } = await query.graph({ entryPoint: "subscription", fields: [ "*", @@ -1011,13 +1014,8 @@ export const GET = async ( }, }) - const { - rows, - metadata: { count, take, skip }, - } = await remoteQuery(query) - res.json({ - subscriptions: rows, + subscriptions, count, limit: take, offset: skip, @@ -1027,7 +1025,7 @@ export const GET = async ( This adds a `GET` API route at `/admin/subscriptions`. -In the route handler, you use the remote query to retrieve a subscription with its orders and customer. +In the route handler, you use Query to retrieve a subscription with its orders and customer. The API route accepts pagination parameters to paginate the subscription list. It returns the subscriptions with pagination parameters in the response. @@ -1036,7 +1034,7 @@ The API route accepts pagination parameters to paginate the subscription list. I Create the file `src/api/admin/subscriptions/[id]/route.ts` with the following content: export const getSubscriptionsAdminHighlight = [ - ["13", "remoteQueryObjectFromString", "Retrieve the subscription with its orders and customer."] + ["13", "graph", "Retrieve the subscription with its orders and customer."] ] ```ts title="src/api/admin/subscriptions/[id]/route.ts" highlights={getSubscriptionsAdminHighlight} @@ -1044,15 +1042,15 @@ import { AuthenticatedMedusaRequest, MedusaResponse, } from "@medusajs/medusa" -import { remoteQueryObjectFromString } from "@medusajs/utils" +import { ContainerRegistrationKeys } from "@medusajs/utils" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) - const query = remoteQueryObjectFromString({ + const { data: [subscription] } = await query.graph({ entryPoint: "subscription", fields: [ "*", @@ -1067,17 +1065,15 @@ export const GET = async ( }, }) - const result = await remoteQuery(query) - res.json({ - subscription: result[0], + subscription, }) } ``` This adds a `GET` API route at `/admin/subscriptions/[id]`, where `[id]` is the ID of the subscription to retrieve. -In the route handler, you retrieve a subscription by its ID using the remote query and return it in the response. +In the route handler, you retrieve a subscription by its ID using Query and return it in the response. In the next section, you’ll extend the Medusa admin and use these API routes to show the subscriptions. @@ -2130,15 +2126,15 @@ import { AuthenticatedMedusaRequest, MedusaResponse, } from "@medusajs/medusa" -import { remoteQueryObjectFromString } from "@medusajs/utils" +import { ContainerRegistrationKeys } from "@medusajs/utils" export const GET = async ( req: AuthenticatedMedusaRequest, res: MedusaResponse ) => { - const remoteQuery = req.scope.resolve("remoteQuery") + const query = req.scope.resolve(ContainerRegistrationKeys.QUERY) - const query = remoteQueryObjectFromString({ + const { data: [customer] } = await query.graph({ entryPoint: "customer", fields: [ "subscriptions.*", @@ -2150,17 +2146,15 @@ export const GET = async ( }, }) - const result = await remoteQuery(query) - res.json({ - subscriptions: result[0].subscriptions, + subscriptions: customer.subscriptions, }) } ``` This adds an API route at `/store/customers/me/subscriptions`. -In the route handler, you retrieve the authenticated customer’s subscriptions using the remote query and return them in the response. +In the route handler, you retrieve the authenticated customer’s subscriptions using Query and return them in the response. ### Cancel Subscription API Route diff --git a/www/apps/resources/app/service-factory-reference/methods/list/page.mdx b/www/apps/resources/app/service-factory-reference/methods/list/page.mdx index 7d01634e04..a79f522149 100644 --- a/www/apps/resources/app/service-factory-reference/methods/list/page.mdx +++ b/www/apps/resources/app/service-factory-reference/methods/list/page.mdx @@ -48,7 +48,7 @@ The method returns an array of the first `15` records matching the filters. -This applies to relations between data models of the same module. To retrieve linked records of different modules, use [remote query](!docs!/advanced-development/modules/remote-query). +This applies to relations between data models of the same module. To retrieve linked records of different modules, use [Query](!docs!/advanced-development/modules/query). diff --git a/www/apps/resources/app/service-factory-reference/methods/listAndCount/page.mdx b/www/apps/resources/app/service-factory-reference/methods/listAndCount/page.mdx index a9507e9c47..089f0fdb17 100644 --- a/www/apps/resources/app/service-factory-reference/methods/listAndCount/page.mdx +++ b/www/apps/resources/app/service-factory-reference/methods/listAndCount/page.mdx @@ -54,7 +54,7 @@ The method returns an array with two items: -This applies to relations between data models of the same module. To retrieve linked records of different modules, use [remote query](!docs!/advanced-development/modules/remote-query). +This applies to relations between data models of the same module. To retrieve linked records of different modules, use [Query](!docs!/advanced-development/modules/query). diff --git a/www/apps/resources/app/service-factory-reference/methods/retrieve/page.mdx b/www/apps/resources/app/service-factory-reference/methods/retrieve/page.mdx index 81bdf24ecb..f813519919 100644 --- a/www/apps/resources/app/service-factory-reference/methods/retrieve/page.mdx +++ b/www/apps/resources/app/service-factory-reference/methods/retrieve/page.mdx @@ -30,7 +30,7 @@ The method returns the record as an object. -This applies to relations between data models of the same module. To retrieve linked records of different modules, use [remote query](!docs!/advanced-development/modules/remote-query). +This applies to relations between data models of the same module. To retrieve linked records of different modules, use [Query](!docs!/advanced-development/modules/query).