【问题标题】:How to know which fields were requested in a GraphQL query?如何知道 GraphQL 查询中请求了哪些字段?
【发布时间】:2019-07-25 19:29:46
【问题描述】:

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

{
  posts {
    author {
      comments
    }
    comments
  }
}

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

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

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

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

【问题讨论】:

标签: graphql apollo apollo-server resolver


【解决方案1】:

这里有几个要点,您可以使用它们来优化查询以提高性能。

  1. 在您的示例中,使用起来会有很大帮助 https://github.com/facebook/dataloader。如果你在你的 通过数据加载器解析器,您将确保调用这些解析器 就一次。这将减少对数据库的调用次数 与您的查询一样,显着证明了 N+1 问题。
  2. 我不确定您需要在帖子中获取哪些确切信息 提前,但如果你知道帖子 ID,你可以考虑做一个 通过将已知 ID 传递给 cmets 来“向前看”。这会 确保您不需要等待帖子,您将避免 graphql 树调用,你可以在没有 cmets 的情况下进行解析 等待帖子。这是优化 GraphQL 的好文章 瀑布请求,您能否给出一个好主意如何优化您的 使用数据加载器查询并向前看 https://blog.apollographql.com/optimizing-your-graphql-request-waterfalls-7c3f3360b051

【讨论】:

    【解决方案2】:

    您需要解析作为其第四个参数传递给解析器的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-fields 的作者也建议今后使用graphql-parse-resolve-info
    猜你喜欢
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 2017-05-10
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    相关资源
    最近更新 更多