我一直在研究一些GraphQL实现,据我了解GraphQL可以让您以Graph的形式遍历数据。
这意味着您会获得一个书本清单,这是一个REST调用。这些书可能有作者姓名。
当用户想要更多有关作者的信息时,他会这样说,然后进行另一个REST调用以获取有关该作者的更多详细信息。
类似地,书籍清单可能有一个名为Publisher的字段,依此类推。 因此,在这里获取数据就像将Book的节点连接到Author或Publisher的节点一样。
但是我已经看到一些实现,其中使用for
循环将来自两个剩余调用的数据进行组合并呈现在UI中。例如呼叫书籍的REST API,然后呼叫撰写这些书籍的作者的REST API。运行for
嵌套的for-loop(n ^ 2复杂度)以合并结果,并在一个摘要视图中显示书籍和作者的信息。
这是可以接受的做法,还是打破了GraphQL不应该做的一些核心概念?
答案 0 :(得分:0)
我不确定我会说这样做“打破了一些核心概念”,但是以这种方式“预先加载”所有对REST端点的调用存在潜在的缺点。 GraphQL允许您为每个字段定义解析器,该解析器确定该字段返回的值。 “父”字段在“子”字段之前被解析,并且“父”的值向下传递给每个“子”的解析器。
假设您有一个这样的架构:
type Query {
book(id: ID): Book
}
type Book {
title: String
author: Author
publisher: Publisher
}
在这里,book
字段将解析为代表一本书的对象,并且该对象将向下传递给title
,author
和publisher
的解析器
如果没有为特定字段提供解析器,则默认行为是在父对象上查找与该字段同名的属性,然后返回该属性。因此,您的book
的解析器可以从某个REST端点(总共3个调用)中获取书籍,作者和出版者,并返回合并的结果。另外,您也可以只获取书籍,然后让author
字段解析器获取作者,而让publisher
字段解析器获取出版商。
他们的关键是仅在请求该字段时才调用解析器。这两种方法的区别在于,您可以查询book
并仅请求标题。 / p>
query SomeQuery {
book(id: 1) {
title
}
}
在这种情况下,如果您预先加载所有API调用,那么您将不必要地对REST端点(对于作者和发布者)进行两次附加调用。
当然,如果您有一个返回书本数组的字段,则可能不希望通过为请求的每本书获取作者来锤击REST端点,因此在这种情况下,同时获取书本和作者可能很有意义全部在根查询中。
这里没有一个正确的答案,因为这两种方法都可能会取舍。这是一个关于如何设计模式,如何使用它以及您可以接受哪些成本的问题。