概述
让我们给我们的超级图添加一些内容 - 从字面上讲!我们将把我们的配乐数据与需要音乐的餐点配对!使用GraphOS,这非常简单:我们只需点击几下!
在本课中,我们将
- 添加一个新的子图到我们的超级图中,使用 Studio
- 检查一个操作的查询计划
介绍食谱
每个人都需要一个好的配乐来搭配他们正在制作的特殊菜肴!为此,我们即将了解食谱 API;它是另一个成熟的GraphQL 服务器,它具有模式、解析器和数据源。
我们可以使用沙盒来探索它。这是端点:
https://poetic-recipes-api-2f18189a9776.herokuapp.com
现在,API 只是一个小型食谱集合。我们可以询问一些事情,例如
- 一个随机食谱
- 其数据库中的所有食谱列表
- 最近添加的食谱
- 特定食谱的配料、烹饪时间、说明等
最酷的部分?它不是一个 .NET 服务器。相反,它是用 JavaScript 编写的,并使用Apollo Server!请记住,这对我们的超级图来说不是问题。我们加入的每个子图都可以使用不同的语言或框架编写。我们即将看到这一点的实际应用!
让我们将这个子图及其全新的功能欢迎到我们的GraphQL API 中 - 我们无需克隆存储库或进行任何调整即可实现。
添加子图
转到您的超级图在 Studio 中的页面,并导航到子图页面。我们可以看到我们的
soundtracks
子图已经在这里,指向我们托管它的位置。点击添加子图。
https://studio.apollographql.com/注意:您也可以使用Rover CLI添加一个子图,就像我们对
soundtracks
子图所做的那样!要查找说明,请单击添加子图旁边的箭头,然后选择使用 Rover CLI 添加子图。我们需要提供关于子图的两件事:它的 URL 和它的名称。
路由 URLhttps://poetic-recipes-api-2f18189a9776.herokuapp.com/子图名称recipeshttps://studio.apollographql.com/然后,单击添加子图。需要花费几分钟时间才能让GraphOS检查该子图是否成功与所有其他现有子图组合并生成一个超级图模式(启动过程所需的所有步骤)。就是这样!
https://studio.apollographql.com/
我们的新超级图模式
让我们通过导航菜单查看变更日志。
我们可以看到我们的图已经扩展了 - 其中包含与食谱相关的类型和字段!我们拥有Ingredient
、Recipe
以及几个添加到我们字段中的新字段,例如allRecipes
和recentlyAddedRecipes
。
所有这些新的类型和字段很可能都来自recipes
子图。我们可以通过转到模式页面来确认哪些字段来自哪个子图。
在引用选项卡下,选择查询后,我们可以看到我们超级图的入口点。在子图列中,指示每个字段来自哪个子图!
我们拥有四个来自我们查询入口点的可用新字段:allRecipes
、randomRecipe
、recentlyAddedRecipes
和一个特定的recipe(id)
。
我们的超级图已经正式扩展了!
发送查询
有了配乐和食谱数据,您是否迫不及待地想测试我们的超级图的功能?让我们尝试发送一个涉及这两个子图的查询。
让我们回到查询选项卡,在模式页面中,我们可以看到我们超级图的所有可用入口点。在操作列中,单击模式页面中recipe
旁边的播放图标。
这将打开 Explorer,并显示“文档”选项卡,其中包含 字段,以及用于构建我们的 查询 的内容。
如果您当前在“操作”面板中有一个 操作,请清除它或打开一个新的 Explorer 选项卡。我们要从这里开始!
在 recipe
下,我们可以看到它的描述——根据 ID 返回特定菜谱——以及 字段,用于 Recipe
类型。让我们添加 name
、cookingTime
、description
和 instructions
。
query Recipe($recipeId: ID!) {recipe(id: $recipeId) {namecookingTimedescriptioninstructions}}
因为此 字段 返回特定菜谱的数据,我们需要为它提供一个 ID 作为 参数。以下是我们可以粘贴到“变量”面板的内容。
{"recipeId": "recgUKbxnQssl9fYc"}
这些是来自 recipes
的数据 子图!让我们将来自 soundtracks
的数据 子图 加入进来!为什么不提取精选播放列表的数据呢?
在 Explorer 中有一个方便的快捷方式来搜索我们架构中的此 字段。按 Command + K
或 Ctrl + K
访问聚光灯搜索。开始输入 featuredPlaylists
,Query.featuredPlaylists
字段 应该会弹出。
我们将选择该 字段,现在我们可以在“文档”面板中直接访问它。这节省了我们几个点击,尤其是当我们的 超级图 继续增长时!
让我们添加 featuredPlaylists
字段,并请求每个播放列表的 name
作为子 字段。
最后,我们将重命名 操作,使其更明确。将其命名为 GetRecipeAndPlaylists
。
您的 查询 现在应该看起来像这样:
query GetRecipeAndPlaylists($recipeId: ID!) {recipe(id: $recipeId) {namecookingTimedescriptioninstructions}featuredPlaylists {name}}
让我们运行它!
哇,我们得到了数据!一个查询,但数据来自两个不同的子图 🤯🎉
查询计划
我们可以通过检查 查询计划 来验证每个 字段 的数据来自哪里。查询计划就像一个操作的蓝图:它包含一组指令,路由器会使用这些指令将较小的操作发送到负责这些特定 字段 的子图。
点击“响应”旁边的箭头,然后选择“查询计划预览”。
我们可以将其视为图表,或者如果我们选择“以文本形式显示计划”图标,可以将其视为文本。
QueryPlan {Parallel {Fetch(service: "recipes") {{recipe(id: $recipeId) {namecookingTimedescriptioninstructions}}},Fetch(service: "soundtracks") {{featuredPlaylists {name}}},},}
我们不用太担心查询计划语法——路由器知道发生了什么!但这在我们开始涉及更多子图和需要优化的更复杂查询时非常有用。
对于这个特定的 查询,我们可以看到 recipe
字段 及其子字段来自 recipes 子图,featuredPlaylists
字段 及其子字段来自 soundtracks
子图。这两个较小的操作并行运行并由各自的子图解析,路由器负责将它们捆绑在一起,并将它们作为一个响应返回给客户端。
添加一个 子图 很容易!但现在,你可能会觉得这两个子图中的数据是分开的,彼此孤立。没有东西可以将 soundtracks 与特定的菜谱直接 连接。毕竟,我们希望用完美的播放列表来烹饪!
新功能:菜谱的推荐播放列表
我们想询问特定菜谱的详细信息:它的描述、说明和配料,以及与之搭配的推荐播放列表!对于每个播放列表,我们还想查看曲目列表。
花点时间查看上面的模型,并练习以架构为先的 设计 方法。以下是一些供您思考的问题:
- 您将如何设计您的 GraphQL 架构 来满足此页面对数据的需求?
- 我们现有的 GraphQL API 中有什么?我们可以添加什么?
- 这个页面的 查询 可能是什么样子的?
架构优先设计
准备好了吗?以下页面需要的哪些数据片段(架构中的类型和 字段):
以及每个播放列表需要什么
梦寐以求的查询
最后,以下是可以为该页面构建的 查询 的样子:
query GetRecipeAndRecommendedSoundtracks {randomRecipe {idnamedescriptioningredients {text}instructionsrecommendedPlaylists {idnamedescriptiontracks {idnameexplicitdurationMs}}}}
注意:您想知道“梦寐以求的 查询”这个词来自哪里吗?请查看 Yelp 的博文,了解更多详细信息。
理想情况下,我们会与前端客户端团队合作来决定和验证这个 查询。在这里,我们已经决定让页面返回一个随机食谱的详细信息(通过 randomRecipe
字段),并且该特定食谱将有一个名为 recommendedPlaylists
的字段。
这个新的 recommendedPlaylists
字段 对于 Recipe
类型应该由 soundtracks
子图 负责,它包含所有与播放列表和曲目相关的内容!
所以我们需要一种方法来连接这两个 子图 之间的数据,以使我们梦寐以求的 查询 能够正常工作(提示:它被称为实体!)。
但首先,让我们设置本地开发环境,以确保我们对 soundtracks
子图 的更改不仅能够正常工作,而且能够与 recipes
子图 相处融洽。
练习
关键要点
- 要添加新的 子图,我们可以使用 Studio UI 或 Rover CLI。
- 我们可以使用 Explorer 查看 路由器 的 查询计划。
接下来
让我们在下一课中为本地开发做好准备。
分享您对本课的疑问和评论
本课程目前处于
您需要一个 GitHub 帐户才能在下方发帖。没有帐户吗? 请在我们的 Odyssey 论坛上发帖。