You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraphQL中关联数据返回异常问题排查求助

问题分析与解决方案

首先咱们直接戳核心问题:你没给Subreddit类型的posts字段编写解析器,而且Query里的posts resolver还写错了结构,这俩问题叠加导致了非空字段返回null的报错。

1. 错误根源拆解

你的Schema里明确规定Subreddit必须返回非空的posts数组([Post!]!),但GraphQL默认解析器只会在当前对象里找同名字段——而你的dummySubreddits数组里的对象根本没有posts属性,所以默认解析器返回了null,直接触发了非空约束的报错。

另外,你Query里的posts resolver写法完全错误:

posts: () => (parent, args) => {
  return dummyPosts.find(obj => obj.subredditId == parent.id);
}

这是嵌套了两层箭头函数,而且find是返回单个元素,Query的posts应该返回所有帖子的数组,不是单个结果。

2. 分步修正方案

第一步:修正Query里的posts resolver

把它改成直接返回所有帖子的数组:

posts: () => dummyPosts,

第二步:添加Subreddit类型的解析器

在resolvers对象里新增Subreddit字段,专门处理它的关联字段posts:

Subreddit: {
  posts: (parent) => {
    // parent参数就是当前查询到的Subreddit对象
    // 用它的id过滤dummyPosts里所有属于这个子版块的帖子
    return dummyPosts.filter(post => post.subredditId === parent.id);
  }
}

这里必须用filter而非find,因为我们要返回多个帖子组成的数组,find只会返回第一个匹配的元素。

第三步:修复createSubreddit的小漏洞

你现在创建子版块后,只是生成了对象但没加到dummySubreddits数组里,导致创建后查不到新的子版块,补上这行代码:

dummySubreddits.push(subreddit);

另外注意idCountSubreddit的自增逻辑,初始值是dummySubreddits.length(3),用idCountSubreddit++会导致第一个新增的id和现有最后一个id重复,建议改成++idCountSubreddit。

3. 完整修正后的resolvers代码

const resolvers = {
  Query: {
    subreddits: () => dummySubreddits,
    subreddit: (parent, args) => {
      return dummySubreddits.find(obj => obj.id == args.id);
    },
    posts: () => dummyPosts, // 修正此处
    post: (parent, args) => {
      return dummyPosts.find(obj => obj.id == args.id);
    }
  },
  Mutation: {
    createSubreddit: (parent, args) => {
      let subreddit = {
        id: ++idCountSubreddit, // 修正自增逻辑
        name: args.name,
        description: args.description,
        contentType: args.contentType,
        ageRestriction: args.ageRestriction
      };
      dummySubreddits.push(subreddit); // 新增这行
      return subreddit;
    }
  },
  // 新增Subreddit类型的关联字段解析器
  Subreddit: {
    posts: (parent) => {
      return dummyPosts.filter(post => post.subredditId === parent.id);
    }
  }
};

4. 额外提示

  • GraphQL的解析器是按类型组织的:每个自定义类型(比如Subreddit、Post)都可以单独写解析器处理字段,尤其是关联字段
  • 区分find和filter:find返回单个匹配项,filter返回所有匹配项组成的数组,对应数组类型的字段必须用filter
  • 首次用graphql-yoga的话,记住它默认会帮你处理很多基础配置,核心还是要把resolvers的结构和逻辑写对

现在再运行你的查询,应该就能得到预期结果啦!

内容的提问来源于stack exchange,提问作者Ibrahim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:09:36