Files
medusa-store/www/apps/book/app/advanced-development/modules/remote-query/page.mdx
Shahed Nasser 964927b597 docs: general fixes and improvements (#7918)
* docs improvements and changes

* updated module definition

* modules + dml changes

* fix build

* fix vale error

* fix lint errors

* fixes to stripe docs

* fix condition

* fix condition

* fix module defintion

* fix checkout

* disable UI action

* change oas preview action

* flatten provider module options

* fix lint errors

* add module link docs

* pr comments fixes

* fix vale error

* change node engine version

* links -> linkable

* add note about database name

* small fixes

* link fixes

* fix response code in api reference

* added migrations step
2024-07-04 17:26:03 +03:00

417 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { TypeList, Tabs, TabsList, TabsTrigger, TabsContent, TabsContentWrapper } from "docs-ui"
export const metadata = {
title: `${pageNumber} Remote Query`,
}
# {metadata.title}
In this chapter, youll 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. Its 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 Medusas commerce modules.
<Note type="check">
- [Enable the isQueryable configuration of the module](../module-links/page.mdx#prerequisite-isqueryable-configuration)
</Note>
---
## 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 models 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<void> {
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 models 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.*"
],
})
```
<Note title="Tip">
`.*` 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`.
</Note>
### 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.
<TypeList
types={[
{
name: "variables",
type: "`object`",
description: "Variables to pass to the query.",
children: [
{
name: "filters",
type: "`object`",
description: "The filters to apply on any of the data model's properties."
}
]
},
]}
sectionTitle="Apply Filters"
/>
---
## 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:
<TypeList types={[
{
name: "rows",
type: "`array`",
description: "The returned records."
},
{
name: "metadata",
type: "`object`",
description: "The pagination details",
children: [
{
name: "skip",
type: "`number`",
description: "The number of records skipped."
},
{
name: "take",
type: "`number`",
description: "The number of records requested to fetch."
},
{
name: "count",
type: "`number`",
description: "The total number of records."
}
]
}
]} sectionTitle="Apply Pagination" />
---
## Using GraphQL
The remote query function alternatively accepts a string with GraphQL syntax as the query.
<Tabs defaultValue="basic" layoutType="vertical" className="mt-2">
<TabsList>
<TabsTrigger value="basic">Basic Usage</TabsTrigger>
<TabsTrigger value="filters">Apply Filters</TabsTrigger>
<TabsTrigger value="sort">Sort Records</TabsTrigger>
<TabsTrigger value="pagination">Apply Pagination</TabsTrigger>
</TabsList>
<TabsContentWrapper>
<TabsContent value="basic" className="[&_h3]:!mt-0">
### 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<void> {
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,
})
}
```
</TabsContent>
<TabsContent value="filters" className="[&_h3]:!mt-0">
### 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",
]
}
)
```
</TabsContent>
<TabsContent value="sort" className="[&_h3]:!mt-0">
### Sort Records with GraphQL
To sort the records by a property, pass in the query an `order` argument whose value is an object. The objects key is the propertys 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)
```
</TabsContent>
<TabsContent value="pagination" className="[&_h3]:!mt-0">
### 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:
<TypeList types={[
{
name: "rows",
type: "`array`",
description: "The returned records."
},
{
name: "metadata",
type: "`object`",
description: "The pagination details",
children: [
{
name: "skip",
type: "`number`",
description: "The number of records skipped."
},
{
name: "take",
type: "`number`",
description: "The number of records requested to fetch."
},
{
name: "count",
type: "`number`",
description: "The total number of records."
}
]
}
]} sectionTitle="Pagination with GraphQL" />
</TabsContent>
</TabsContentWrapper>
</Tabs>