6. 实现查询解析器
4m

src/resolvers.js中,在我们的 tracksForHome 中,让我们添加参数。

参数的顺序在这里很重要。如果我们只添加一个参数,那么该函数会将其视为第一个可选参数: parent。我们需要 contextValue,它是第三个参数,才能访问我们的

我们 需要前两个参数,所以按照惯例,我们将它们命名为下划线:第一个(parent)为一个下划线,第二个(args)为两个下划线。

对于 contextValue,我们将解构它以访问它的子对象 dataSources。我们可以省略第四个参数, info,因为我们不会使用它。

server/src/resolvers.js
const resolvers = {
Query: {
// get all tracks, will be used to populate the homepage grid of our web client
tracksForHome: (_, __, { dataSources }) => {},
},
};
代码挑战!

编辑 spaceCats 字段的解析器函数的参数,以遵循上面解释的约定。您需要从 contextValue 参数解构 dataSources。该函数目前不应返回任何内容。

从我们的 dataSources 对象中,我们将获得对我们的 trackAPI(此处为小写,因为它是我们扩展 RESTDataSourceTrackAPI 类实例)及其 getTracksforHome 方法的访问权限,该方法是我们之前构建的。

我们的 tracksForHome 将返回该 TrackAPI 方法的结果。

server/src/resolvers.js
const resolvers = {
Query: {
// get all tracks, will be used to populate the homepage grid of our web client
tracksForHome: (_, __, { dataSources }) => {
return dataSources.trackAPI.getTracksForHome();
},
},
};
module.exports = resolvers;
代码挑战!

Query.spaceCats 字段创建一个解析器函数。遵循上面解释的四个可选参数的约定。使用 dataSources 对象访问 spaceCatsAPI.getSpaceCats() 方法并返回结果。使用箭头函数语法。

现在,这将处理获取我们轨道的数据,但我们还需要与每个轨道关联的作者。我们需要调用 getAuthor 方法来自我们的 TrackAPI

那么,这个调用应该放在哪里呢?嗯,我们的 tracksForHome 可以 始终 遍历返回的轨道数据,获取每个轨道的 authorId 属性,并使用它调用 getAuthor。但是,我们的 tracksForHome 始终 获取作者数据,即使对于没有请求该数据的查询也是如此!

相反,让我们添加另一个 ,专门用于轨道作者。为此,我们将向我们的 resolvers 对象添加另一个键,称为 Track,表示它用于我们模式中的 Track 类型。在该 Track 键内部将是 另一个 对象,其中包含一个 author ,在这里我们将定义我们的

server/src/resolvers.js
const resolvers = {
Query: {
// ...
},
Track: {
author: (parent, args, contextValue, info) => {},
},
};

这次我们需要 parent ,所以让我们将其保留在 函数中。我们可以用下划线替换 args。我们将解构 contextValue 以访问 dataSources 键以获得我们的 TrackAPI。然后省略 info,因为我们不需要它。

server/src/resolvers.js
const resolvers = {
Query: {
// ...
},
Track: {
author: (parent, _, { dataSources }) => {},
},
};

TrackAPIgetAuthor 方法需要一个 authorId。我们将从传递给 parent 中获取此值。该 parent 包含我们的 tracksForHome 返回的数据,并且由于 tracksForHome 返回列表,所以 将遍历该列表,并为每个轨道调用一次 author 。它将当前轨道作为 parent 的值传递,使我们能够提取 authorId

如果我们要 console.log(parent),在我们的 author 中,打印的值将看起来完全像从我们的 RESTDataSource 返回的轨道列表中的单个原始轨道。

我们的 Track.author 解析器的 parent 参数中将包含哪些信息?

让我们从 parent 解构 authorId。然后,我们将调用 getAuthor 方法来自我们的 dataSources.trackAPI 方法,并将 authorId 传递进去。最后,我们将返回结果。

server/src/resolvers.js
const resolvers = {
Query: {
// get all tracks, will be used to populate the homepage grid of our web client
tracksForHome: (_, __, { dataSources }) => {
return dataSources.trackAPI.getTracksForHome();
},
},
Track: {
author: ({ authorId }, _, { dataSources }) => {
return dataSources.trackAPI.getAuthor(authorId);
},
},
};
代码挑战!

SpaceCat.missions 字段创建一个解析器函数。遵循上面解释的四个可选参数的约定。使用 dataSources 对象访问 spaceCatsAPI.getMissions() 方法。它从 parent 中获取 catId 参数并返回结果。使用箭头函数语法。

作为最佳实践,在处理您的 时,尽量使解析器函数尽可能精简。这样,您就能使您的 API 对未来的更改更具弹性。您可以安全地重构数据获取代码,或将源从 REST API 完全更改为数据库,而不会破坏您的 API。这还能使您的解析器易于阅读和理解,这在您定义越来越多的解析器时非常有用!

现在,你可能想知道传递给我们 dataSources 对象的 来自哪里。我们什么时候将其添加到 contextValue 参数中?现在,它 没有 被添加。如果我们运行我们的服务器,它将对我们的 TrackAPI 一无所知。它也不了解我们的 !让我们确保所有三部分都相互连接。

上一页

分享您关于本课程的问题和评论

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

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