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

时间:2018-05-29 09:40:20

标签: graphql graphql-java

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

对于以下架构:

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
        }
    }
}

数据存储:

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

  

如果有任何类似的例子,请分享详细信息。 (参考graphql-java获得答案会很有帮助)

2 个答案:

答案 0 :(得分:0)

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

data loader收集有关fields加载哪些table以及要使用的where过滤器的信息。

我没有在Java中使用GraphQL,所以我只能告诉你如何自己实现它。

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

答案 1 :(得分:0)

DataFetchingEnvironment可通过DataFetchingEnvironment#getSelectionSet访问子选项。这意味着,在您的情况下,您可以从nodes解析器中了解到neighbors也是必需的,因此您可以JOIN正确地准备结果。

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