5. 添加子图
10m

概述

让我们将我们的列表数据与来自过去客人的评论相结合。使用,这非常简单:只需点击几下即可!

在本课中,我们将

  • 添加一个新的 到我们的 中,使用 Studio
  • 检查一个

介绍评论

我们即将了解评论 API;它是一个功能齐全的 ,具有模式、 和数据提取器。

reviews 服务收集并提供客人的反馈。我们可以 它以获取其数据库中的所有评论,或提交新的评论。

让我们将这个 和全新的功能集成到我们的 API 中——我们可以通过克隆存储库并立即报告其模式来实现。无需任何调整!

克隆 reviews

在您的终端中,导航到 listings 目录之外,以便您位于主 dgs-federation 项目文件夹中。然后,运行以下命令来克隆 reviews

dgs-federation
git clone https://github.com/apollographql-education/odyssey-federation-dgs-reviews.git reviews

注意: 我们在上面的命令中添加了 reviews 标志。这将在名为 reviews 的文件夹中克隆提供的存储库,以确保清晰度。

现在我们的项目结构如下

📦 dgs-federation
┣ 📂 listings
┣ 📂 reviews
┗ 📂 router

让我们在新的 IDE 窗口中打开 reviews 并启动它。如果您使用的是 IntelliJ,请找到绿色的播放按钮,或在存储库终端中运行以下命令。

reviews
./gradlew bootRun

添加子图

让我们将我们的 reviews 模式发布到注册中心。

复制下面的命令,用 的值替换 APOLLO_GRAPH_REF。然后,在打开到 reviews 目录的终端中,粘贴并运行它。

reviews
rover subgraph publish <APOLLO_GRAPH_REF> \
--name reviews \
--schema ./src/main/resources/schema/schema.graphqls \
--routing-url https://127.0.0.1:8090/graphql

注意: listings 在本地运行在端口 8080 上,而 reviews 运行在 8090 上。确保在发布 reviews 模式时,您引用了正确的端口号!

现在,让我们返回 Studio,并导航到左侧菜单中的 子图 选项卡。我们会看到我们新的 reviews 已经报告了——我们的 也增长了!

studio.apollographql.com

A screenshot of the Subgraphs page, showing two subgraphs: listings and reviews

我们新的超级图模式

接下来,让我们通过导航菜单查看 变更日志,以了解 reviews 向 API 添加了哪些新功能和功能。

studio.apollographql.com

The Changelog page in Studio, showing additions to the schema from the reviews subgraph

我们可以看到我们的 已经增长——包含关于评论的所有类型和 !我们有两个新的 ReviewSubmitReviewResponse。我们还有 ReviewInput 作为新的输入类型。并且我们有两个新的根 Query.allReviewsMutation.submitReview

所有这些新的类型和 应该都来自 reviews 。我们可以通过前往 模式 页面来确认哪些 来自哪个子图。

参考 选项卡下,选择 查询,我们可以看到进入我们 的入口点。 子图 列指示每个 来自哪个

studio.apollographql.com

The Schema page in Studio, showing fields on the Query type and which subgraph provides them

在这里,我们会看到 reviews 贡献的新 allReviews

我们还可以在 对象 下查看添加到我们模式中的新

studio.apollographql.com

The Schema page in Studio, showing the object types and which subgraph provides them

我们的 已正式增长!

发送查询

评论和列表的数据触手可及;您是否迫不及待地想测试我们 的强大功能?让我们尝试发送一个涉及两个

让我们回到 模式 页面中的 查询 选项卡,在那里我们可以看到进入我们 的所有可用入口点。在 模式 页面中的 操作 列中,单击 allReviews 旁边的播放图标。

studio.apollographql.com

The play button beside the allReviews field outlined

这将打开 Explorer,并显示文档选项卡,其中包含 以及我们可以用来构建 的内容。

studio.apollographql.com

The Explorer with the Documentation tab opened to the listing field

注意: 如果您在 操作 面板中当前有一个 ,请清除它或打开新的 Explorer 选项卡。我们想要从这里开始!

allReviews 下,我们可以看到它的描述——"数据库中的所有评论列表"——以及每个返回的 Review 类型上可用于 。让我们添加所有字段:idtextrating

query GetAllReviews {
allReviews {
id
text
rating
}
}

这些数据来自 reviews !现在让我们从 listings 中引入数据:为什么我们不提取特定房源的数据呢?

在 Explorer 中有一个方便的快捷方式,可以搜索我们的模式以查找该 。按下 Command + KCtrl + K 访问聚光灯搜索。开始键入 listing,则 Query.listing 应该会弹出。

studio.apollographql.com

The Explorer with the search modal pulled up, and Query.listing selected from the dropdown

让我们添加 listing 并请求其 title

最后,我们将重命名 以使其更明确。将其命名为 GetAllReviewsAndListing

您的 现在应该看起来像这样:

query GetAllReviewsAndListing($listingId: ID!) {
allReviews {
id
text
rating
}
listing(id: $listingId) {
title
}
}

以及在 Variables 部分:

{
"listingId": "listing-1"
}

让我们运行它!

哇哦,我们得到了数据!一个查询,但数据来自两个独立的子图 🤯🎉

查询计划

我们可以通过检查 查询计划 来验证每个 的数据的确切来源。 就像 的蓝图: 用于将较小的操作发送到负责这些特定 的一组指令。

点击 Response 面板中的下拉菜单,选择 Query Plan

studio.apollographql.com

The Response panel opened to the Query Plan, which shows how the router will execute the query to the subgraphs

我们可以将 视为图表,或者如果我们选择 "Show plan as text" 图标,则可以将其视为文本。我们不必过分担心 的语法—— 知道发生了什么!但这在我们开始使用更多 和更复杂的查询(需要优化)时非常有用。

studio.apollographql.com

Query plan preview in text format, showing which subgraph each field is fetched from

对于这个特定的 ,我们可以看到 "Parallel" 这个词,表示 可以同时发出两个独立的请求:一个到 reviews,另一个到 listings。这些请求可以并行运行,因为 listingsreviews 都不依赖于对方的响应来解析自己的数据。

我们还可以看到 allReviews 及其子字段来自 reviews (即 Fetch(service: "reviews") 部分),而 listing 及其子字段来自 listings 。这两个较小的 并行运行并由其自己的子图解析,而 负责将数据捆绑起来,以单个响应的形式返回给客户端。

添加 相当简单!但是您可能感觉这两个子图中的数据仍然是独立的和孤立的。没有直接 连接 房源和评论,反之亦然。

新功能:房源的评分和评论

我们希望能够 关于特定房源的详细信息:标题、描述、床位数量和便利设施,以及对其的评论!让我们更进一步——也包含房源的 overallRating,它是根据所有评分计算得出的。

A preview of what our listing data should look like, supplemented with reviews and overall rating

理想的 看起来像这样:

query GetListingAndReviews {
listing(id: "listing-1") {
title
description
numOfBeds
amenities {
name
category
}
overallRating
reviews {
id
text
}
}
}

注意:为了便于在课程中进行参考,我们在 中内联包含了房源的 id。实际上,这个 id 会被提取到 中。

让我们深入研究我们的 reviews 数据,看看如何构建这个功能,并实现我们理想的

数据在 reviews

当我们启动 reviews 服务器时,它会自动在其内存数据库中播种一些示例评论。

reviews 表定义了四列: idtextratinglistingId。下表说明了这些数据的组合。

idtextratinglistingId
1"哇,真是太棒的体验了!我以前从未住过洞穴,所以有点没准备。幸运的是,这个房源拥有我需要的安全保障和一切设施,让我可以应对任何情况。"4"listing-1"
2"100% 享受荒野体验。如果您不是冒险家或户外爱好者,请不要预订。"5"listing-2"
3"嘛,说真的,可以更好。我期待更多。湖是唯一的亮点。"2"listing-3"

那个 listingId 正是我们需要用来将特定评论与它所写的房源相关联的东西。

只有一个问题:除了我们数据库中的这一列之外,我们 reviews 并不知道 什么 是 "房源"。同样,我们的 listings 也不了解 reviews!即使它们是同一个 的一部分,每个 都是独立存在的。

我们需要一种方法来连接这两个 之间的数据,以实现我们梦寐以求的 功能(提示:它被称为实体!)。这将涉及对两个子图进行一些更改,因此我们将首先设置正确的 开发环境。这将确保我们对一个子图所做的任何更改不仅按预期工作,而且还与另一个子图完美配合。

练习

要添加新的子图,GraphOS 需要知道哪些值?

主要收获

  • 要添加新的 ,我们可以使用 Studio UI 或
  • 我们可以使用 Explorer 查看

下一步

在下一课中,让我们为本地开发做好准备。

上一页

分享您关于本课的问题和意见

本课程目前处于

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

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