GraphQLError:ID 无法表示值:<Buffer...>”

Pie*_*e_T 4 mongoose graphql nestjs

我有一个基本的 Nestjs - Mongoose - Graphql api,我定义了两个模式:UserEvent

//USER Schema
@Schema()
export class User extends Document {
  @Prop()
  username: string;

  @Prop({ required: true })
  password: string;

  @Prop({ required: true, unique: true })
  email: string;

  @Prop({ required: true, unique: true })
  handle: string;

  @Prop()
  avatar: string;
}

export const UserSchema = SchemaFactory.createForClass(User);
Run Code Online (Sandbox Code Playgroud)
//EVENT schema
@Schema()
export class Event extends Document {
  @Prop({
    type: MongooseSchema.Types.ObjectId,
    ref: User.name,
    required: true,
  })
  creator: GqlUser;

  @Length(5, 30)
  @Prop({ required: true })
  title: string;

  @Length(5, 200)
  @Prop({ required: true })
  description: string;

  @Prop()
  createdDate: string;

  @Prop()
  public: boolean;

  @Prop()
  active: boolean;
}

export const EventSchema = SchemaFactory.createForClass(Event);

Run Code Online (Sandbox Code Playgroud)

EventSchema, 字段creator中键入为MongooseSchema.Types.ObjectId指向User

我的events.resolvers.ts看起来像这样:


@Resolver(of => GqlEvent)
export class EventsResolvers {
  constructor(private eventsService: EventsService) {}

  @Query(returns => [GqlEvent])
  async events() {
    return this.eventsService.findAll();
  }

  @Mutation(returns => GqlEvent)
  async createEvent(
    @Args('createEventInput') createEventInput: CreateEventDto,
  ) {
    return this.eventsService.create(createEventInput);
  }
}

Run Code Online (Sandbox Code Playgroud)

事件DTO:

@ObjectType()
export class GqlEvent {
  @Field(type => ID)
  id: string;

  @Field(type => GqlUser)
  creator: GqlUser;

  @Field()
  title: string;

  @Field()
  description: string;

  @Field()
  createdDate: string;

  @Field()
  public: boolean;

  @Field()
  active: boolean;
}

@InputType()
export class CreateEventDto {
  @Field(type => ID)
  creator: GqlUser;

  @Field()
  @Length(5, 30)
  title: string;

  @Field()
  @Length(5, 200)
  description: string;

  @Field()
  @IsBoolean()
  public: boolean;
}
Run Code Online (Sandbox Code Playgroud)

这样,Nestjs 生成以下 gql 模式(为了清楚起见,我跳过与用户 CRUD 相关的部分):

# ------------------------------------------------------
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
# ------------------------------------------------------

type GqlUser {
  id: ID!
  username: String!
  handle: String!
  avatar: String!
  email: String!
}

type GqlEvent {
  id: ID!
  creator: GqlUser!
  title: String!
  description: String!
  createdDate: String!
  public: Boolean!
  active: Boolean!
}

type Query {
  events: [GqlEvent!]!
}

type Mutation {
  createEvent(createEventInput: CreateEventDto!): GqlEvent!
}


input CreateEventDto {
  creator: ID!
  title: String!
  description: String!
  public: Boolean!
}

Run Code Online (Sandbox Code Playgroud)

什么有效:createEvent突变正确地将文档插入数据库中:

{
"_id":{"$oid":"5f27eacb0393199e3bab31f4"},
"creator":{"$oid":"5f272812107ea863e3d0537b"},
"title":"test event",
"description":"a test description",
"public":true,
"active":true,
"createdDate":"Mon Aug 03 2020",
"__v":{"$numberInt":"0"}
}

Run Code Online (Sandbox Code Playgroud)

我的问题:当我尝试请求子字段时出现以下错误creator

Gql查询:

query {
  events {
    id
    creator {
      id
    }
    createdDate
    public
    description
    title
    active
  }
}

Run Code Online (Sandbox Code Playgroud)

回复 :

"errors": [
    {
      "message": "ID cannot represent value: <Buffer 5f 27 28 12 10 7e a8 63 e3 d0 53 7b>",
      "locations": [
        {
          "line": 6,
          "column": 7
        }
      ],
      "path": [
        "createEvent",
        "creator",
        "id"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "message": "ID cannot represent value: <Buffer 5f 27 28 12 10 7e a8 63 e3 d0 53 7b>",
          "stacktrace": [
            "GraphQLError: ID cannot represent value: <Buffer 5f 27 28 12 10 7e a8 63 e3 d0 53 7b>",...

Run Code Online (Sandbox Code Playgroud)

由于当我省略creator字段时它工作正常,我知道猫鼬MongooseSchema.Types.ObjectId会导致 gql 模式出现问题......但我找不到适当的方法来修复它。提前感谢帮助

Pie*_*e_T 7

creator这实际上与该字段没有填充的事实有关。

更改自

async findAll(): Promise<Event[]> {
    return this.eventModel
      .find()
      .exec();
  }
Run Code Online (Sandbox Code Playgroud)

async findAll(): Promise<Event[]> {
    return this.eventModel
      .find()
      .populate('creator')
      .exec();
  }
Run Code Online (Sandbox Code Playgroud)

解决了我的问题。该错误消息有点误导。