在 GraphQL 中以最佳方式获取数据

Fetching the data optimally in GraphQL

如何编写解析器,以便我可以在每个解析器中生成数据库子查询并有效地组合所有这些查询并一次获取数据?

对于以下架构:

type Node {
    index: Int!
    color: String!
    neighbors(first: Int = null): [Node!]!
}

type Query {
    nodes(color: String!): [Node!]!
}

schema {
    query: Query
}

执行以下查询:

{
    nodes(color: "red") {
        index
        neighbors(first: 5) {
            index
        }
    }
}

数据存储:

在我的数据存储中,节点和邻居存储在单独的表中。我想编写一个解析器,以便我们可以最佳地获取所需的数据。

If there are any similar examples, please share the details. (It would be helpful to get an answer in reference to graphql-java)

推荐和最常用的方法是使用 data loader

A data loader 收集关于从哪个 fields 加载哪个 table 以及要使用哪个 where 过滤器的信息。

我没有在 Java 中使用过 GraphQL,所以我只能给你指导如何自己实现它。

  1. 创建数据加载器实例并将其作为 context 参数传递给解析器。
  2. 您的解析器应将 table namefield names 列表和 where conditions 列表传递给数据加载器和 return 承诺。
  3. 一旦所有解析器都已执行,您的数据加载器应该合并这些列表,这样您最终每个 table 只需要一个查询。
  4. 您应该 remove duplicate field 名称和 combine the where conditions 使用 or 关键字。
  5. 查询执行后,您可以 return 所有这些数据到您的解析器并让他们过滤数据(因为我们使用 or 关键字组合条件)
  6. 作为一项高级功能,您的数据加载器可以在 return 将数据发送到解析器之前应用 where 条件,这样他们就不必过滤它们。

DataFetchingEnvironment 通过 DataFetchingEnvironment#getSelectionSet 提供对子选择的访问。这意味着,在您的情况下,您可以从 nodes 解析器知道还需要 neighbors,因此您可以适当地 JOIN 并准备结果。

getSelectionSet 当前实施的一个 限制 是它不提供有关 条件选择 的信息。因此,如果您要处理接口和联合,则必须手动收集从 DataFetchingEnvironment#getField 开始的子选择。这很可能会在 graphql-java.

的未来版本中得到改进