在src/resolvers.js
中,在我们的 tracksForHome
解析器,添加参数。
在这里参数的顺序很重要。如果我们只添加一个参数,那么函数会将其视为第一个可选参数:parent
。我们需要第三个参数context
来访问我们的数据源。
我们不需要前两个参数,所以按照惯例,我们将它们命名为下划线:第一个参数(parent
)使用一个下划线,第二个参数(args
)使用两个下划线。
对于context
,我们将它解构以访问其子对象dataSources
。我们也可以省略第四个参数info
,因为我们不会使用它。
const resolvers = {Query: {// get all tracks, will be used to populate the homepage grid of our web clienttracksForHome: (_, __, { dataSources }) => {},},};
编辑 spaceCats
字段解析器函数的参数,遵循上述说明,并使用箭头函数语法。你需要从上下文参数中解构 dataSources
。目前函数不应返回任何内容。
从我们的 dataSources
对象,我们将获得访问我们的 trackAPI
(在这里是小写字母,因为它是我们扩展了 RESTDataSource
类的 TrackAPI
类的实例)以及我们之前构建的 getTracksforHome
方法的权限。
我们的 tracksForHome
resolver 将返回 那个 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;
为查询的字段 spaceCats
创建一个解析器函数。按照上面解释的约定使用四个可选参数,并使用箭头函数语法。使用 dataSources
对象访问 spaceCatsAPI.getSpaceCats()
方法并返回结果。
这处理了获取我们轨道的数据,但我们还需要每个轨道相关联的作者。我们需要调用我们的 TrackAPI
中的 getAuthor
方法。
那么这个调用应该放在哪里呢?好吧,我们的 tracksForHome
resolver 可以遍历返回的轨迹数据,取每个轨迹的 authorId
属性,然后调用 getAuthor
。但是,然后我们的 tracksForHome
resolver 总是获取作者数据,即使对于根本不请求它的查询也不例外!
相反,让我们为轨道的作者添加另一个 resolver。为此,我们将在我们的 resolvers
对象中添加另一个键,键名为 Track
,表示它是我们模式中 Track
类的。在该 Track
键内部将有一个 另一个 对象,具有一个 author
字段,其中我们将定义我们的 resolver。
const resolvers = {Query: {// ...},Track: {author: (parent, args, context, info) => {},},};
这次我们需要 parent
argument,所以让我们将其保留在 resolver 函数中。我们可以将 args
替换为下划线。我们从 context
中解构以访问我们的 dataSources
键来访问我们的 TrackAPI。然后省略 info
,因为我们不需要它。
const resolvers = {Query: {// ...},Track: {author: (parent, _, { dataSources }) => {},},};
TrackAPI的
getAuthor方法需要一个
authorId。我们将从这个
parent
参数传递给
resolver。这个
parent
参数包含了我们的
tracksForHome
resolver返回的数据,
因为tracksForHome
返回一个列表,Apollo Server会遍历这个列表并在每个track
上调用resolver一次。
如果在我们的author resolver函数内部
console.log(parent)
,打印出的值将会与我们的RESTDataSource
返回的原始tracks列表中的单个track一模一样。
Track.author
resolver的parent
参数中会包含哪些信息?现在让我们从parent 参数中提取
authorId
。然后,我们将从dataSources.trackAPI
方法调用getAuthor
方法,传入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
字段创建一个resolver函数。按照上述说明使用四个可选参数的约定。dataSources
对象用于访问spaceCatsAPI.getMissions()
方法。catId
参数从parent
传入并返回结果。
最好实践是,当你在临床上集中解毒和data sources工作时,尽量保持解析函数尽可能薄。这样做可以让你的API对未来的变化更具弹性。重写你的数据获取代码,或完全从REST API更改为数据库,而无需破坏你的API。
现在,你可能想知道传给我们的 dataSources
对象是从哪里来的。我们是什么时候将它添加到 context
参数中的?现在它 还没有 被添加。如果我们运行服务器,它将没有任何关于我们的 TrackAPI
的了解。它也同样不知道我们的 resolvers!让我们确保这三部分彼此连接。
分享你对这个课程的问题和评论
你的反馈有助于我们改进!如果你卡住了或感到困惑,请告诉我们,我们会帮助你。所有评论都是公开的,必须遵循 Apollo行为准则。请注意,已解决的或已处理的评论可能会被删除。
你需要一个GitHub账号来发布以下内容。还没有吗? 请在我们的Odyssey论坛上发帖。