GraphQL 仅在查询中请求特定字段时才获取
GraphQL only fetch if certain field is requested in query
一个非常基本的模式:
type Foo {
id: String!
name: String!
createdAt: Date!
bars: [Bar]
}
type Bar {
id: String!
name: String!
fooId: String!
}
然后是我的 Resolver 映射:
Query: {
foo:
async (
_: any,
{ id }: { id: string }
) => {
const { data: fooObj } = await httpRequest({
url: `/api/foos/${id}`
});
const barsResponse = await httpRequest({
url: `/api/bars/?fooId=${id}`
});
const response = {
...fooObj.foo,
bars: barsResponse.data.bars
};
return response;
}
}
如果用户执行以下查询:
{
foo(id: "123456"){
bars {
name
}
}
}
查询解析器正确获取并 returns 正确形状的正确数据,但是,运行 这个查询:
{
foo(id: "123456"){
name
}
}
理想情况下不会执行第二次获取请求来获取 bars
。如果查询包含 bars
?
,我如何拆分查询解析器以便它只运行 Bars 提取
是的,将获取逻辑移动到 bars
的解析器中:
const resolvers = {
Query: {
foo: () => {...},
},
Foo: {
bars: ({ id }) => {
const { data: { bars } } = await httpRequest({
url: `/api/bars/?fooId=${id}`
})
return bars
},
},
}
传递给每个解析器的第一个参数是父字段解析到的值。只要 Query.foo
的解析器内部返回的内容包括 id
,Foo.bars
.
的解析器就可以使用它
除非请求该字段(并且父字段未解析为空),否则不会调用该字段的解析器。因此,仅当请求中存在该字段时,才会触发对 /api/bars
的调用。
如果您愿意,也可以继续获取根级别的所有内容。传递给解析器的第四个参数是一个 GraphQLResolveInfo
对象,它将包含有关请求的信息,包括请求了哪些字段。您可以解析此对象并让您的根解析器相应地运行。但是,对于像这样更简单的场景,那就太过分了。
一个非常基本的模式:
type Foo {
id: String!
name: String!
createdAt: Date!
bars: [Bar]
}
type Bar {
id: String!
name: String!
fooId: String!
}
然后是我的 Resolver 映射:
Query: {
foo:
async (
_: any,
{ id }: { id: string }
) => {
const { data: fooObj } = await httpRequest({
url: `/api/foos/${id}`
});
const barsResponse = await httpRequest({
url: `/api/bars/?fooId=${id}`
});
const response = {
...fooObj.foo,
bars: barsResponse.data.bars
};
return response;
}
}
如果用户执行以下查询:
{
foo(id: "123456"){
bars {
name
}
}
}
查询解析器正确获取并 returns 正确形状的正确数据,但是,运行 这个查询:
{
foo(id: "123456"){
name
}
}
理想情况下不会执行第二次获取请求来获取 bars
。如果查询包含 bars
?
是的,将获取逻辑移动到 bars
的解析器中:
const resolvers = {
Query: {
foo: () => {...},
},
Foo: {
bars: ({ id }) => {
const { data: { bars } } = await httpRequest({
url: `/api/bars/?fooId=${id}`
})
return bars
},
},
}
传递给每个解析器的第一个参数是父字段解析到的值。只要 Query.foo
的解析器内部返回的内容包括 id
,Foo.bars
.
除非请求该字段(并且父字段未解析为空),否则不会调用该字段的解析器。因此,仅当请求中存在该字段时,才会触发对 /api/bars
的调用。
如果您愿意,也可以继续获取根级别的所有内容。传递给解析器的第四个参数是一个 GraphQLResolveInfo
对象,它将包含有关请求的信息,包括请求了哪些字段。您可以解析此对象并让您的根解析器相应地运行。但是,对于像这样更简单的场景,那就太过分了。