GraphQL嵌套解析器问题:查询Song.author需显式指定Song.id的解决办法咨询
问题根源与解决方案
你的问题核心在于Song.author解析器的参数逻辑错误:你当前误用了Song自身的id作为查询Author的参数,但实际你的数据里每个Song存储的是关联作者的authorId字段。另外你可能误解了GraphQL解析器的父对象传递规则——不管客户端是否请求了某些字段,解析器拿到的父对象都是数据源返回的完整实体(只要根解析器返回了完整数据)。
修复步骤
1. 修正Song.author解析器逻辑
把解析器中传递给author查询的参数,从Song的id改成Song对象的authorId字段,这才是关联作者的正确标识:
const songsLinksResolvers = mergeInfo => ({ Song: { author: ({ authorId }, args, context, info) => { return mergeInfo.delegate( 'query', 'author', { id: authorId }, // 使用Song的authorId查询对应Author context, info, ); } }, });
2. 验证修复效果
现在执行你之前的「无效查询示例」:
{ song(id: 1) { author { name } } }
会正确返回预期结果:
{ "data": { "song": { "author": { "name": "John" } } } }
为什么之前必须显式查询Song.id?
之前你错误地用Song的id去匹配Author的id,这只是碰巧在Song id=1时和Author id=1重合才「有效」。当客户端不查询Song.id时,虽然父对象里仍然包含id字段(根解析器返回了完整的Song对象),但用Song的id去查Author本质是错误的关联逻辑,大部分场景下会返回null或错误。
关于info对象的误区
你之前尝试用info对象是没必要的,GraphQL解析器的第一个参数(父对象)会携带根解析器返回的完整数据,和客户端是否请求了所有字段无关。你只需要从父对象中取出正确的关联字段(authorId)即可,不需要依赖客户端的查询字段。
完整修改后的核心代码片段
这里是修正后的songsLinksResolvers部分,其余代码保持不变:
const songsLinksResolvers = mergeInfo => ({ Song: { author: ({ authorId }, args, context, info) => { return mergeInfo.delegate( 'query', 'author', { id: authorId }, context, info, ); } }, });
内容的提问来源于stack exchange,提问作者s.susini
相关产品推荐
相关产品推荐

