如何知道在 GraphQL 查询中请求了哪些字段?
How to know which fields were requested in a GraphQL query?
我写了一个 GraphQL 查询,如下所示:
{
posts {
author {
comments
}
comments
}
}
我想知道如何获取 posts
解析器中请求的子字段的详细信息。
我想这样做是为了避免解析器的嵌套调用。我正在使用 ApolloServer 的 DataSource
API.
我可以更改 API 服务器以一次获取所有数据。
我正在使用 ApolloServer 2.0,也欢迎任何其他避免嵌套调用的方法。
这里有几个要点,您可以使用它们来优化查询以提高性能。
- 在你的例子中,使用
https://github.com/facebook/dataloader。如果您在您的
通过数据加载器解析器,您将确保调用这些解析器
就一次。这将减少对数据库的调用次数
显着,因为在您的查询中证明了 N+1 问题。
- 我不确定您需要在 posts 中获得哪些确切信息
提前,但如果你知道 post 个 ID,你可以考虑做一个
"look ahead" 通过将已知的 ID 传递到评论中。这会
确保您不需要等待 posts 并且您将避免
graphql 树调用,你可以在没有的情况下解决评论
等待 post 秒。这是一篇优化 GraphQL 的好文章
瀑布式请求,您能否给出如何优化您的
使用数据加载器查询并向前看
https://blog.apollographql.com/optimizing-your-graphql-request-waterfalls-7c3f3360b051
您需要解析作为第四个参数传递给解析器的 info
对象。这是对象的类型:
type GraphQLResolveInfo = {
fieldName: string,
fieldNodes: Array<Field>,
returnType: GraphQLOutputType,
parentType: GraphQLCompositeType,
schema: GraphQLSchema,
fragments: { [fragmentName: string]: FragmentDefinition },
rootValue: any,
operation: OperationDefinition,
variableValues: { [variableName: string]: any },
}
您可以自己遍历该领域的 AST,但最好还是使用现有的库。我推荐 graphql-parse-resolve-info。还有许多其他库,但 graphql-parse-resolve-info
是一个非常完整的解决方案,实际上由 postgraphile
在幕后使用。用法示例:
posts: (parent, args, context, info) => {
const parsedResolveInfo = parseResolveInfo(info)
console.log(parsedResolveInfo)
}
这将按照这些行记录一个对象:
{
alias: 'posts',
name: 'posts',
args: {},
fieldsByTypeName: {
Post: {
author: {
alias: 'author',
name: 'author',
args: {},
fieldsByTypeName: ...
}
comments: {
alias: 'comments',
name: 'comments',
args: {},
fieldsByTypeName: ...
}
}
}
}
您可以遍历生成的对象并相应地构造您的 SQL 查询(或一组 API 请求,或其他)。
我写了一个 GraphQL 查询,如下所示:
{
posts {
author {
comments
}
comments
}
}
我想知道如何获取 posts
解析器中请求的子字段的详细信息。
我想这样做是为了避免解析器的嵌套调用。我正在使用 ApolloServer 的 DataSource
API.
我可以更改 API 服务器以一次获取所有数据。
我正在使用 ApolloServer 2.0,也欢迎任何其他避免嵌套调用的方法。
这里有几个要点,您可以使用它们来优化查询以提高性能。
- 在你的例子中,使用 https://github.com/facebook/dataloader。如果您在您的 通过数据加载器解析器,您将确保调用这些解析器 就一次。这将减少对数据库的调用次数 显着,因为在您的查询中证明了 N+1 问题。
- 我不确定您需要在 posts 中获得哪些确切信息 提前,但如果你知道 post 个 ID,你可以考虑做一个 "look ahead" 通过将已知的 ID 传递到评论中。这会 确保您不需要等待 posts 并且您将避免 graphql 树调用,你可以在没有的情况下解决评论 等待 post 秒。这是一篇优化 GraphQL 的好文章 瀑布式请求,您能否给出如何优化您的 使用数据加载器查询并向前看 https://blog.apollographql.com/optimizing-your-graphql-request-waterfalls-7c3f3360b051
您需要解析作为第四个参数传递给解析器的 info
对象。这是对象的类型:
type GraphQLResolveInfo = {
fieldName: string,
fieldNodes: Array<Field>,
returnType: GraphQLOutputType,
parentType: GraphQLCompositeType,
schema: GraphQLSchema,
fragments: { [fragmentName: string]: FragmentDefinition },
rootValue: any,
operation: OperationDefinition,
variableValues: { [variableName: string]: any },
}
您可以自己遍历该领域的 AST,但最好还是使用现有的库。我推荐 graphql-parse-resolve-info。还有许多其他库,但 graphql-parse-resolve-info
是一个非常完整的解决方案,实际上由 postgraphile
在幕后使用。用法示例:
posts: (parent, args, context, info) => {
const parsedResolveInfo = parseResolveInfo(info)
console.log(parsedResolveInfo)
}
这将按照这些行记录一个对象:
{
alias: 'posts',
name: 'posts',
args: {},
fieldsByTypeName: {
Post: {
author: {
alias: 'author',
name: 'author',
args: {},
fieldsByTypeName: ...
}
comments: {
alias: 'comments',
name: 'comments',
args: {},
fieldsByTypeName: ...
}
}
}
}
您可以遍历生成的对象并相应地构造您的 SQL 查询(或一组 API 请求,或其他)。