5. 解析链
5m

📥 检索模块详细信息

要检索给定轨道的模块详细信息,我们需要使用GET track/:id/modules我们在 REST API中提供的

让我们尝试一下该端点,再次为其提供我们的轨道 ID c_0

我们得到响应,是一个包含我们需要详细信息的模块数组。

Screenshot of REST API docs with focus on the GET track/:id/modules endpoint

我们的轨道页现在需要 idtitlelength。让我们更新我们的 TrackAPI以调用此端点。

💾 更新 RESTDataSource

server/src/datasources文件夹中,打开 track-api.js文件。

让我们创建一个名为 getTrackModules的方法。它将 trackId作为参数。在其中,它将对 track/${trackId}/modules端点进行 get调用,并返回结果。

getTrackModules(trackId) {
return this.get(`track/${trackId}/modules`);
}

现在我们可以在 中使用这个新数据源方法。让我们跳转回 resolvers.js 文件中的 server/src 文件夹。

首先,让我们确定应该在什么地方放置调用获取曲目模块的详细信息。我们知道在 track 中需要这些信息。但是我们是否应该将调用添加到 track 中?

// EXAMPLE ONLY - should we add the getTrackModules call here in the track resolver?
track: async (_, { id }, { dataSources }) => {
// get track details
const track = await dataSources.trackAPI.getTrack(id);
// get module details for the track
const modules = await dataSources.trackAPI.getTrackModules(id);
// shape the data in the way that the schema expects it
return { ...track, modules };
};

我们当然可以这样做。这是我们在 Lift-off II 中面临的一个类似问题,当时我们试图找出在哪里检索每个曲目的作者详细信息。我们最终将该逻辑提取到一个不同的 中: Track.author.

在 Lift-off II 中,我们将作者获取逻辑提取到一个不同的解析器中的原因是什么?(提示:如果你需要复习,请继续往下读,并在准备就绪后返回这个问题!)

出于完全相同的原因,我们需要对我们的模块详细信息做同样的事情。让我们深入探究原因。

⛓️ 解析链

我们经常会在 中看到这种特定的模式。当我们编写 时,我们经常有嵌套的对象和 。以这个查询为例:

query track(id:c_0') {
title
author {
name
}
}

请记住,一个 负责在您的架构中填充 的数据。它从 中检索数据。在我们的案例中,我们为我们的 track 设置了一个解析器,该解析器从 REST API /track/:id终端点检索数据。

Illustration showing a Query.track resolver retrieving data from the track/:id REST endpoint

它返回我们的 预期的某些属性,例如 title。它没有作者姓名,但它有 authorId,这是一个我们可以用于我们 REST API 中另一个终端点 author/:id终端点的 ID。

我们能够告知这个 相同的 调用 author/:id终端点,然后将结果整合到我们的 预期的格式中。

然而,这意味着 有点忙得不可开交了!如果 不要求作者信息,那么解析器将 仍然执行所有这些不必要​​的步骤。

Illustration showing a Query.track resolver looking overworked as it retrieves data from two REST endpoints

所以,与其把所有工作都交给可怜的 Query.track ,我们可以为 Track.author创建另一个解析器函数。此 负责为特定曲目检索作者信息。有了它,我们便形成了一个解析器链!

Illustration showing a Query.track resolver linked with the Track.author resolver in a resolver chain

还有 中的第一个参数—— parentparent指的是链中前一个 函数的返回数据!这就是我们如何在 Track.author 中从 track对象中获取 authorIdauthorId。此外, Track.author 只会在 请求该 时才被调用!

Illustration showing the Query.track resolver passing the data to the Track.author resolver as a `parent` parameter

此模式可保持每个 的可读性、易理解性,还能提高对未来变更的适应性。

解析器参数
解析器函数填充架构中数据 
 
 。该函数有四个参数。第一个, 
 
, 包含 中前一个函数返回的数据
 
。第二个,args, 是一个包含传递到字段的所有 
 
 的对象。我们使用第三个参数 
 
, 访问 
 
 ,例如数据库或 REST API。最后,第四个参数 
 
, 包含关于操作状态的信息属性。

将此框中的项目拖至上面的空格

  • 解析器链

  • parent

  • 变量

  • 参数

  • 信息

  • 数据源

  • contextValue

  • 字段

  • 类型

✍️ 向链中添加新的解析器

回到我们特定的问题,让我们使用这个链的概念来为Track.modules创建一个解析器。

我们将在Track.author的下面添加这个resolvers.js文件中:

modules: ({id}, _, {dataSources}) => {
return dataSources.trackAPI.getTrackModules(id);
},

我们将解构第一个参数来从父级中检索id属性,它就是跟踪的id。我们不需要那个args参数,因此它可以是一个下划线,然后解构第三个contextValue参数以获取dataSources属性。

在里面,我们可以返回调用我们的dataSources.trackAPI.getTrackModules方法的结果,传入跟踪的id

这就是我们的所要完成的任务!有了它后,我们已经更新了我们的解析器、数据源和模式,并且准备处理我们的新

上一个

分享你对本课程提出的问题和意见

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

你需要拥有 GitHub 帐号才能在下方进行发布。没有 GitHub 帐号? 改为在我们的 Odyssey 论坛中发布。