Nach diesem Tutorial habe ich ein Mungo-Modell: (Ich verwende den Begriff "Account" anstelle von "Todo", aber es ist dasselbe).
const Account = mongoose.model('Account', new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
name: String
}));
und ein GraphQLObjectType:
const AccountType = new GraphQLObjectType({
name: 'account',
fields: function () {
return {
id: {
type: GraphQLID
},
name: {
type: GraphQLString
}
}
}
});
und eine GraphQL-Mutation, um eine davon zu erstellen:
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);
});
});
}
}
}
})
Nach dem Ausführen der Abfrage:
mutation {
add(name: "Potato")
{
id,
name
}
}
in GraphiQL bekomme ich die Antwort:
{
"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"
}
}
}
Die Erstellung des Objekts war erfolgreich und ich kann es in MongoDB Compass sehen:
es scheint jedoch ein Problem beim Lesen des Wertes zu geben.
Wie kompatibel sind GraphQLID
und mongoose.Schema.Types.ObjectId
? Wenn sie nicht kompatibel sind, missverstehe ich das Tutorial, insbesondere die Verwendung von:
newAccount.id = newAccount._id;
? Ich kann nicht sagen, ob der Fehler von GraphQL, MongoDB, Mongoose oder etwas anderem ausgelöst wurde.
EDIT
Alle Informationen zum Fehler
Die ID kann keinen Wert darstellen: {_bontype:\"ObjectID \", id:}
wäre sehr hilfreich. Ich habe das Gefühl, dass es mir sagt, dass es kein BSON-Objekt serialisieren konnte, aber dann wird es serialisiert angezeigt. Sogar zu wissen, welche Tech (Mongo? Mongoose? Graphql?) Den Fehler erzeugte, würde helfen. Ich habe kein Glück mit Google.
EDIT 2
Dies wurde verursacht durch eine Änderung des kürzlich eingeführten graphql-Pakets, und es gibt eine PR / erwarte eine Fusion, die es auflöst.
Ich habe kein Problem gefunden und diesen Code mit einer meiner vorhandenen Codebasis ausgeführt. Außer dass ich die Mutation in GraphQLObjectType
eingepackt habe.
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);
});
});
}
}
});
Um das Arbeitsbeispiel zu erhalten: Clone Repo. In diesem Repo verwendet die App v0.13.2
und Sie verwenden v14.0.2
, die über npm i graphql
installiert ist. Downgrade von graphql
auf v0.13.2
.
Ich habe ID
verwendet und es funktioniert gut! Ursache Ihres Problems ist nicht der Typ der ID! Es ist nur so, dass Sie es mit einem falschen Wert angeben: ObjectID('actuall id')
Um dieses Problem zu beheben, rufen Sie die Funktion toJson
für jede abgerufene Daten auf oder fügen Sie einfach eine virtuelle id
wie folgt hinzu:
YourSchema.virtual('id').get(function() {
return this.toJSON()._id
}
Ich habe gerade festgestellt, dass _id
vom Typ ObjectID
ist, aber implizit in String
umgewandelt wird. Wenn Sie also Ihren Moose-Model-ID-Typ als String
anstelle von mongoose.Schema.Types.ObjectId
definieren, sollte dies funktionieren. Wenn Sie Ihren aktuellen Code (aus dem Tutorial compose.com) verwenden, der _id in die ID kopiert, führt dies dazu, dass in Mongo (nach dem Speichern) die _id vom Typ ObjectID
und Ihre Modell-ID den Typ string haben.
Mit anderen Worten, stattdessen
const Account = mongoose.model('Account', new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
name: String
}));
Mach das
const Account = mongoose.model('Account', new mongoose.Schema({
id: String,
name: String
}));