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

Node+GraphQL项目存关联数据到MongoDB时ID序列化报错排查

Apollo GraphQL关联Mongoose ObjectId时ID序列化错误

我在Node项目里用Apollo开发简易博客的GraphQL API,后台用Mongoose存MongoDB。保存Post数据时触发以下错误:

"GraphQLError: ID cannot represent value: { type: "Buffer", data: [Array] }", "at GraphQLScalarType.serialize (/Users/name/projects/graphtime/node_modules/graphql/type/scalars.js:301:11)"

推测问题出在Post关联Author的插入环节,想知道是Schema定义有误,还是GraphiEditor的查询方式有问题。

数据库Schema

import mongoose from "mongoose";

const authorSchema = new mongoose.Schema({
  name: { type: String, required: true },
  avatar: { type: String },
});

export const Author = mongoose.model('Author', authorSchema);

const postSchema = new mongoose.Schema({
  title: { type: String, required: true },
  authors: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Author'
    }
  ]
});

export const Post = mongoose.model('Post', postSchema);

GraphQL Schema

type Post {
    id: ID!
    title: String
    authors: [Author]
}

type Author {
    id: ID!
    name: String
    avatar: String
}

type Mutation {
    addPost(
        title: String!,
        authors: [ID!],
    ): Post
}

GraphQL Resolver

const resolvers = {
  Mutation: {
    addPost: (_, args, context) => {
      const newPost = new Post({
        title: args.title,
        authors: args.authors,
      });
      return newPost.save();
    },
  },
};

执行的查询语句(数据库已存在ID为63babc44e18d174016b03433的Author)

mutation {
  addPost(
    title: "New Post",
    authors: ["63babc44e18d174016b03433"],
  ) {
    title
    authors {
      id
      name
    }
  }
}

解决方案

问题出在Resolver未正确关联查询Author数据:
当addPost保存Post后,返回的authors字段是Mongoose的ObjectId数组,而非实际的Author文档。GraphQL的ID标量无法直接序列化ObjectId对象(其内部包含Buffer结构),因此触发报错。

修复方式有两种:

  1. 在Mutation中直接关联查询
    修改addPost的Resolver,保存后调用populate方法拉取关联的Author数据:
const resolvers = {
  Mutation: {
    addPost: (_, args, context) => {
      const newPost = new Post({
        title: args.title,
        authors: args.authors,
      });
      // 保存后populate关联的authors
      return newPost.save().then(post => post.populate('authors'));
    },
  },
};
  1. 为Post类型添加authors字段解析器
    在Resolver中新增Post类型的解析逻辑,自动查询关联的Author:
const resolvers = {
  Post: {
    // 解析Post的authors字段,根据ObjectId查询对应的Author文档
    authors: (parent) => Author.find({ _id: { $in: parent.authors } })
  },
  Mutation: {
    addPost: (_, args, context) => {
      const newPost = new Post({
        title: args.title,
        authors: args.authors,
      });
      return newPost.save();
    },
  },
};

两种方式都能让GraphQL拿到完整的Author文档,从而正确序列化id字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:01:02