0

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

这意味着你会得到一个书籍列表,它是一个 REST 调用。这些书可能有作者姓名。

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

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

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

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

4

1 回答 1

1

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

假设您有这样的架构:

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

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

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

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

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

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

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

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

这里没有一个正确的答案,因为无论哪种方式都可能需要权衡取舍。这是一个关于您的架构如何设计、如何使用以及您可以接受的成本的问题。

于 2018-10-21T01:35:21.997 回答