繁体   English   中英

跨mongoose和GraphQL的ObjectId字段使用的正确类型是什么?

[英]What is the correct type to use for an ObjectId field across mongoose and GraphQL?

本教程之后 ,我有一个猫鼬模型:(我使用术语“帐户”而不是“Todo”,但它是一样的)

const Account = mongoose.model('Account', new mongoose.Schema({
  id: mongoose.Schema.Types.ObjectId,
  name: String
}));

和GraphQLObjectType:

const AccountType = new GraphQLObjectType({
  name: 'account',
  fields: function () {
    return {
      id: {
        type: GraphQLID
      },
      name: {
        type: GraphQLString
      }
    }
  }
});

和GraphQL突变创建其中之一:

const mutationCreateType = new GraphQLObjectType({
  name: 'Mutation',
  fields: {
    add: {
      type: AccountType,
      description: 'Create new account',
      args: {
        name: {
          name: 'Account Name',
          type: new GraphQLNonNull(GraphQLString)
        }
      },
      resolve: (root, args) => {
        const newAccount = new Account({
          name: args.name
        });

        newAccount.id = newAccount._id;

        return new Promise((resolve, reject) => {
          newAccount.save(err => {
            if (err) reject(err);
            else resolve(newAccount);
          });
        });
      }
    }
  }
})

运行查询后:

mutation {
  add(name: "Potato")
  {
    id,
    name
  }
}

在GraphiQL中,我得到了响应:

{
  "errors": [
    {
      "message": "ID cannot represent value: { _bsontype: \"ObjectID\", id: <Buffer 5b 94 eb ca e7 4f 2d 06 43 a6 92 20> }",
      "locations": [
        {
          "line": 33,
          "column": 5
        }
      ],
      "path": [
        "add",
        "id"
      ]
    }
  ],
  "data": {
    "add": {
      "id": null,
      "name": "Potato"
    }
  }
}

对象的创建是成功的,我可以在MongoDB Compass中看到它:

从MongoDB Compass显示创建的对象

但阅读价值似乎有问题。

如何兼容是GraphQLIDmongoose.Schema.Types.ObjectId 如果它们不兼容,我是否误解了教程,特别是它的使用:

newAccount.id = newAccount._id;

我无法判断GraphQL,MongoDB或Mongoose或其他东西是否抛出了错误。

编辑

有关错误的任何信息

ID不能代表值:{_bsontype:\\“ObjectID \\”,id:}

非常有帮助的。 我觉得它告诉我它无法序列化一个BSON对象..然后它显示它序列化。 即使知道什么技术(mongo?mongoose?graphql?)产生错误也会有所帮助。 我对谷歌没有任何好运。

编辑2

这是由最近引入的graphql包的更改引起的,并且有一个等待合并的PR解决了它。

我没有发现问题,并使用我现有的代码库运行此代码。 除了我在GraphQLObjectType包装了变异。

const Mutation = new GraphQLObjectType({
    name: 'Mutation',
    fields: {
        addAccount: {
            type: AccountType,
            description: 'Create new account',
            args: {
                name: {
                    name: 'Account Name',
                    type: new GraphQLNonNull(GraphQLString)
                }
            },
            resolve: (root, args) => {
                const newAccount = new Account({
                    name: args.name
                });

                newAccount.id = newAccount._id;

                return new Promise((resolve, reject) => {
                    newAccount.save(err => {
                        if (err) reject(err);
                        else resolve(newAccount);
                    });
                });
            }
        }
    });

获取工作示例: 克隆回购。 在这个repo中,应用程序使用v0.13.2 ,你使用的v14.0.2通过npm i graphql安装的npm i graphql 降级graphqlv0.13.2

我使用ID ,它工作正常! 你的问题的原因不是id的类型! 这是因为你提供了错误的值: ObjectID('actuall id')

为了解决这个问题,请为每个获取的数据调用toJson函数,或者只是添加如下的虚拟id

YourSchema.virtual('id').get(function() {
    return this.toJSON()._id
}

所以我刚发现_idObjectID类型,但似乎隐式地转换为String 因此,如果您将mongoose模型id类型定义为String而不是mongoose.Schema.Types.ObjectId那么它应该可以工作。 使用将_id复制到id的当前代码(来自compose.com教程),结果将是Mongo(保存后),_id将是ObjectID类型,您的模型ID将是string类型。

换句话说,而不是这个

const Account = mongoose.model('Account', new mongoose.Schema({
  id: mongoose.Schema.Types.ObjectId,
  name: String
}));

做这个

const Account = mongoose.model('Account', new mongoose.Schema({
  id: String,
  name: String
}));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM