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

GraphQL merging data from multiple REST calls

我一直在研究一些 GraphQL 实现,我的理解是 GraphQL 允许您以图形的形式遍历数据。

这意味着您获得了一个 REST 调用的图书列表。这些书可能有作者姓名。

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

同样,书籍列表可能有一个名为 Publisher 的字段等等。 因此,您在这里获取数据就像将 Book 的节点连接到 Author 或 Publisher 的节点一样。

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

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

我不确定我会说这样做是 "breaking some core concepts",但是 "front loading" 您以这种方式对 REST 端点的所有调用都有一个潜在的缺点。 GraphQL 允许你为每个字段定义一个解析器,它决定了字段 return 的值是什么。 "parent" 字段在其 "children" 字段之前解析,并且 "parent" 的值传递给每个 "child" 的解析器。

假设您有这样的架构:

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

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

在这里,book 字段将解析为代表一本书的 object,并且 object 将传递给 titleauthor, 和 publisher.

如果没有为特定字段提供解析器,默认行为是在 parent object 上查找与该字段同名的 属性,并且 return那个。因此,book 的解析器可以从某个 REST 端点(总共 3 个调用)获取书籍、作者和出版商,并 returned 组合结果。或者,您可以只获取图书,让 author 字段解析器获取作者,让 publisher 字段解析器获取出版商。

它们的关键是只有在请求该字段时才会调用解析器。这两种方法之间的区别在于您可能会查询 book 并且仅请求标题。

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

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

当然,如果您有一个 return 书籍数组的字段,您可能不想通过获取所请求的每本书的作者来打击您的 REST 端点,因此在这些情况下它可能会在根查询中获取所有书籍和作者的意义。

这里没有唯一的正确答案,因为可能有 trade-offs 两种选择。这是一个关于你的架构如何设计、如何使用以及你可以接受的成本的问题。