如何知道Apollo graphql查询中需要哪些子解析器?

时间:2019-03-04 13:11:46

标签: graphql apollo apollo-server resolver

我写了一个如下的grapqhl查询

例如

   posts {
      author {
        comments {
         }
       }
     comments
    }

我想从posts解析器中了解-我如何才能获得有关预先需要的other resolvers的详细信息?

我想这样做是为了避免解析器的嵌套调用,我编写了一个api服务器,它通过'DataSources'调用graphql-server来获取数据。

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

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

2 个答案:

答案 0 :(得分:1)

在这里,您可以使用几个要点来优化查询的性能。

  1. 在您的示例中,使用将有很大帮助 https://github.com/facebook/dataloader。如果您在 通过数据加载器的解析器,您将确保调用这些解析器 就一次。这将减少对数据库的调用次数 就像在查询中显示的N + 1问题一样。
  2. 我不确定您需要在帖子中获取哪些确切信息 提前,但是如果您知道帖子ID,可以考虑进行 通过将已知的ID传递到注释中来“向前看”。这将 确保您不需要等待帖子,并且可以避免 graphql树调用,您可以解析注释而无需 等待帖子。这是一篇关于优化GraphQL的好文章 瀑布请求,您可能会想出如何优化自己的好方法 用数据加载器查询并向前看 https://blog.apollographql.com/optimizing-your-graphql-request-waterfalls-7c3f3360b051

答案 1 :(得分:1)

您需要解析作为解析器第四个参数传递到解析器的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请求集,或其他)。