GraphQL合并来自多个REST调用的数据

时间:2018-10-20 19:31:32

标签: graphql graphql-js graphql-java express-graphql

我一直在研究一些GraphQL实现,据我了解GraphQL可以让您以Graph的形式遍历数据。

这意味着您会获得一个书本清单,这是一个REST调用。这些书可能有作者姓名。

当用户想要更多有关作者的信息时,他会这样说,然后进行另一个REST调用以获取有关该作者的更多详细信息。

类似地,书籍清单可能有一个名为Publisher的字段,依此类推。 因此,在这里获取数据就像将Book的节点连接到Author或Publisher的节点一样。

但是我已经看到一些实现,其中使用for循环将来自两个剩余调用的数据进行组合并呈现在UI中。例如呼叫书籍的REST API,然后呼叫撰写这些书籍的作者的REST API。运行for嵌套的for-loop(n ^ 2复杂度)以合并结果,并在一个摘要视图中显示书籍和作者的信息。

这是可以接受的做法,还是打破了GraphQL不应该做的一些核心概念?

1 个答案:

答案 0 :(得分:0)

我不确定我会说这样做“打破了一些核心概念”,但是以这种方式“预先加载”所有对REST端点的调用存在潜在的缺点。 GraphQL允许您为每个字段定义解析器,该解析器确定该字段返回的值。 “父”字段在“子”字段之前被解析,并且“父”的值向下传递给每个“子”的解析器。

假设您有一个这样的架构:

type Query {
  book(id: ID): Book
}

type Book {
  title: String
  author: Author
  publisher: Publisher
}

在这里,book字段将解析为代表一本书的对象,并且该对象将向下传递给titleauthorpublisher的解析器

如果没有为特定字段提供解析器,则默认行为是在父对象上查找与该字段同名的属性,然后返回该属性。因此,您的book的解析器可以从某个REST端点(总共3个调用)中获取书籍,作者和出版者,并返回合并的结果。另外,您也可以只获取书籍,然后让author字段解析器获取作者,而让publisher字段解析器获取出版商。

他们的关键是仅在请求该字段时才调用解析器。这两种方法的区别在于,您可以查询book并仅请求标题。 / p>

query SomeQuery {
  book(id: 1) {
    title
  }
}

在这种情况下,如果您预先加载所有API调用,那么您将不必要地对REST端点(对于作者和发布者)进行两次附加调用。

当然,如果您有一个返回书本数组的字段,则可能不希望通过为请求的每本书获取作者来锤击REST端点,因此在这种情况下,同时获取书本和作者可能很有意义全部在根查询中。

这里没有一个正确的答案,因为这两种方法都可能会取舍。这是一个关于如何设计模式,如何使用它以及您可以接受哪些成本的问题。