在src/resolvers.js
中,在我们的 tracksForHome
解析器中,让我们添加参数。
参数的顺序在这里很重要。如果我们只添加一个参数,那么该函数会将其视为第一个可选参数: parent
。我们需要 contextValue
,它是第三个参数,才能访问我们的 数据源。
我们 不 需要前两个参数,所以按照惯例,我们将它们命名为下划线:第一个(parent
)为一个下划线,第二个(args
)为两个下划线。
对于 contextValue
,我们将解构它以访问它的子对象 dataSources
。我们可以省略第四个参数, info
,因为我们不会使用它。
const resolvers = {Query: {// get all tracks, will be used to populate the homepage grid of our web clienttracksForHome: (_, __, { dataSources }) => {},},};
编辑 spaceCats
字段的解析器函数的参数,以遵循上面解释的约定。您需要从 contextValue
参数解构 dataSources
。该函数目前不应返回任何内容。
从我们的 dataSources
对象中,我们将获得对我们的 trackAPI
(此处为小写,因为它是我们扩展 RESTDataSource
的 TrackAPI
类实例)及其 getTracksforHome
方法的访问权限,该方法是我们之前构建的。
我们的 tracksForHome
解析器 将返回该 TrackAPI
方法的结果。
const resolvers = {Query: {// get all tracks, will be used to populate the homepage grid of our web clienttracksForHome: (_, __, { dataSources }) => {return dataSources.trackAPI.getTracksForHome();},},};module.exports = resolvers;
为 Query.spaceCats
字段创建一个解析器函数。遵循上面解释的四个可选参数的约定。使用 dataSources
对象访问 spaceCatsAPI.getSpaceCats()
方法并返回结果。使用箭头函数语法。
现在,这将处理获取我们轨道的数据,但我们还需要与每个轨道关联的作者。我们需要调用 getAuthor
方法来自我们的 TrackAPI
。
那么,这个调用应该放在哪里呢?嗯,我们的 tracksForHome
解析器 可以 始终 遍历返回的轨道数据,获取每个轨道的 authorId
属性,并使用它调用 getAuthor
。但是,我们的 tracksForHome
解析器 将 始终 获取作者数据,即使对于没有请求该数据的查询也是如此!
相反,让我们添加另一个 解析器,专门用于轨道作者。为此,我们将向我们的 resolvers
对象添加另一个键,称为 Track
,表示它用于我们模式中的 Track
类型。在该 Track
键内部将是 另一个 对象,其中包含一个 author
字段,在这里我们将定义我们的 解析器。
const resolvers = {Query: {// ...},Track: {author: (parent, args, contextValue, info) => {},},};
这次我们需要 parent
参数,所以让我们将其保留在 解析器 函数中。我们可以用下划线替换 args
。我们将解构 contextValue
以访问 dataSources
键以获得我们的 TrackAPI。然后省略 info
,因为我们不需要它。
const resolvers = {Query: {// ...},Track: {author: (parent, _, { dataSources }) => {},},};
该 TrackAPI
的 getAuthor
方法需要一个 authorId
。我们将从传递给 parent
参数 的 解析器 中获取此值。该 parent
参数 包含我们的 tracksForHome
解析器 返回的数据,并且由于 tracksForHome
返回列表,所以 Apollo Server 将遍历该列表,并为每个轨道调用一次 author
解析器。它将当前轨道作为 parent
的值传递,使我们能够提取 authorId
。
如果我们要 console.log(parent)
,在我们的 author
解析器 中,打印的值将看起来完全像从我们的 RESTDataSource
返回的轨道列表中的单个原始轨道。
Track.author
解析器的 parent
参数中将包含哪些信息?让我们从 parent
参数 解构 authorId
。然后,我们将调用 getAuthor
方法来自我们的 dataSources.trackAPI
方法,并将 authorId
传递进去。最后,我们将返回结果。
const resolvers = {Query: {// get all tracks, will be used to populate the homepage grid of our web clienttracksForHome: (_, __, { 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 论坛中发布。