如何知道 GraphQL 查询中请求了哪些字段?

Wit*_*ult 7 resolver apollo graphql apollo-server

我编写了一个 GraphQL 查询,如下所示:

{
  posts {
    author {
      comments
    }
    comments
  }
}
Run Code Online (Sandbox Code Playgroud)

我想知道如何获取有关posts解析器中请求的子字段的详细信息。

我想这样做是为了避免解析器的嵌套调用。我正在使用 ApolloServer 的DataSourceAPI。

我可以更改 API 服务器以一次获取所有数据。

我正在使用 ApolloServer 2.0,也欢迎任何其他避免嵌套调用的方法。

Dan*_*den 12

您需要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 },
}
Run Code Online (Sandbox Code Playgroud)

您可以自己遍历该领域的 AST,但最好使用现有的库。我推荐graphql-parse-resolve-info。还有许多其他库,但它graphql-parse-resolve-info是一个非常完整的解决方案,实际上由postgraphile. 用法示例:

posts: (parent, args, context, info) => {
  const parsedResolveInfo = parseResolveInfo(info)
  console.log(parsedResolveInfo)
}
Run Code Online (Sandbox Code Playgroud)

这将沿着这些行记录一个对象:

{
  alias: 'posts',
  name: 'posts',
  args: {},
  fieldsByTypeName: {
    Post: {
      author: {
        alias: 'author',
        name: 'author',
        args: {},
        fieldsByTypeName: ...
      }
      comments: {
        alias: 'comments',
        name: 'comments',
        args: {},
        fieldsByTypeName: ...
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以遍历结果对象并相应地构建您的 SQL 查询(或一组 API 请求,或其他任何内容)。

  • [graphql-fields](https://github.com/robrichard/graphql-fields/issues/27#issuecomment-577412938) 的作者还建议继续使用“graphql-parse-resolve-info”。 (2认同)