11. 实体和查询计划
5m

概述

我们已经设置了我们的定义,但路由器究竟如何使用这些实体?

在本课中,我们将

  • 了解路由器如何使用实体和从多个连接数据
  • 了解表示和引用如何协同工作

让我们来看一个示例查询

假设客户端请求应用程序的最新评论。在他们的中,他们会请求每个评论的 ID、评论和评分,以及每个评论所在位置的名称。

query GetLatestReviews {
latestReviews {
id
comment
rating
location {
name
}
}
}
Client sends a request to the router

现在该路由器大显身手了!

步骤 1:构建查询计划

正如我们之前所见,路由器首先构建一个查询计划,它指示将哪些请求发送到哪些

路由器从传入的的顶级开始,latestReviews。借助,路由器看到latestReviewsreviews 中定义。

因此,路由器从向reviews 发送请求开始构建查询计划。

The router uses the supergraph schema to build a query plan, starting with the reviews subgraph

路由器会持续这样做一段时间,检查查询中的每个,并将其与进行比较,并将其添加到查询计划中。对于idcommentratinglocation,它们都属于reviews

The router continues to build the query plan

但当路由器到达name (针对特定Location时),它会从中看到,只有Location.name可以通过locations 解析(因为Location.name 是在那里定义的)。

The router sees that Location.name belongs to the locations subgraph

这意味着路由器将不得不连接来自不同子图的数据。

要做到这一点,路由器需要从reviews 获取更多信息:每个评论对应的Location对象的实体表示。

请记住,表示是路由器用来在不同子图之间跟踪特定对象的。要为Location对象创建实体表示,路由器需要位置的类型名称及其主键(在本例中是id )。

Illustration of an entity representation as a passport

路由器可以从reviews 获取这两个字段。

Illustration of an entity representation as a passport

接下来,路由器会向其查询计划中添加另一个操作,以请求locations 中的位置name

The router adds a query for location name to the query plan

这样一来,查询中的所有字段都已在查询计划中得到考虑。现在该进入下一步:执行计划。

步骤 2:查询 reviews 子图

路由器首先请求reviews 中的数据。

The reviews resolves all the requested as it normally would, including the representations for all the requested location objects.

The router sends an operation to the reviews subgraph

This doesn't know that the plans to do anything special with the location's id or typename. It just sends back the data to the router like it was asked.

The reviews subgraph sends back the data to the router

With that, the 's taken care of the first part of the ! The next step is to retrieve the name from the locations .

Next up on the query plan, the location's name

步骤 3:查询 locations 子图

Remember the _entities that showed up in our after we first defined an ? This is where it comes back into the story!

The builds a request using the _entities .

This takes in an called representations, which takes in, well, a list of representations! This is where the entity representations that the received from the reviews will go.

In the same request, the adds the rest of the left in the (in this case, the location's name).

The router uses the entities field

The sends this request to the location's .

To resolve the _entities , the locations uses its reference resolver. Remember this is a special function used to return all the that this contributes.

The locations looks at the __typename value of each reference object to determine which 's reference to use. In this case, because typename is "Location", the locations knows to use the Location 's reference .

The resolveReference resolver

The Location reference runs once for each representation in the . Each time, it uses the entity representation's primary key to return the corresponding Location object.

The Location reference resolver resolves each entity representation using the primary key

After the locations finishes resolving the request, it sends the data back to the .

Locations subgraph returns data to the router

这就是执行阶段的全部内容!

步骤 4:向客户端发送最终响应

现在,将从reviewslocations 收集到的所有数据组合成一个 JSON 对象。最后,将最终对象发送回客户端。

The router finally returns data to the client

练习

以下哪个步骤**不**属于路由器构建和执行查询计划的一部分?

关键要点

  • 需要从不同的查询时,它还会请求当前正在查询的子图的表示。这些表示将在后续_entities 中使用,设置为representations 的值。
  • 参考获取每个表示,并返回其请求的匹配数据。

接下来

现在我们确切地知道中发生了什么,以及这些部分是如何组合在一起的!在下一课中,我们将深入代码并从引用来自开始。

上一课

分享您对本课的疑问和评论

您的反馈将帮助我们改进!如果您卡住或困惑,请告诉我们,我们会帮助您。所有评论都是公开的,必须遵守 Apollo 行为准则。请注意,已解决或已处理的评论可能会被删除。

您需要一个 GitHub 帐户才能在下面发布。没有? 请在我们的 Odyssey 论坛中发布。