Après ce tutoriel , j'ai un modèle de mangouste: (J'utilise le terme "Compte" au lieu de "Todo", mais c'est la même chose)
const Account = mongoose.model('Account', new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
name: String
}));
et un GraphQLObjectType:
const AccountType = new GraphQLObjectType({
name: 'account',
fields: function () {
return {
id: {
type: GraphQLID
},
name: {
type: GraphQLString
}
}
}
});
et une mutation GraphQL pour en créer un:
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);
});
});
}
}
}
})
Après avoir exécuté la requête:
mutation {
add(name: "Potato")
{
id,
name
}
}
dans GraphiQL, je reçois la réponse:
{
"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"
}
}
}
La création de l'objet a réussi et je peux le voir dans MongoDB Compass:
mais il semble y avoir un problème de lecture de la valeur.
Dans quelle mesure GraphQLID
et mongoose.Schema.Types.ObjectId
sont-ils compatibles? S'ils ne sont pas compatibles, je ne comprends pas le didacticiel, en particulier l'utilisation de:
newAccount.id = newAccount._id;
? Je ne peux pas dire si l'erreur provient de GraphQL, de MongoDB, de Mongoose ou de quelque chose d'autre.
MODIFIER
Toute information sur l'erreur
L'ID ne peut pas représenter la valeur: {_bsontype:\"ObjectID \", id:}
serait très utile. Je sens que cela me dit qu'il ne peut pas sérialiser un objet BSON .. mais ensuite, il l'affiche sérialisé. Même savoir quelle technologie (mongo? Mongoose? Graphql?) Générait l'erreur aiderait. Je n'ai aucune chance avec Google.
EDIT 2
Cela a été causé par une modification du paquetage graphql introduit récemment, et il y a un PR en attente de fusion qui le résout.
Je n'ai pas trouvé de problème et ai exécuté ce code avec l'une de mes bases de code existantes. Sauf que j'ai enveloppé la mutation dans la 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);
});
});
}
}
});
Pour obtenir l'exemple de travail: Clone the repo. Dans ce dépôt, l'application utilise v0.13.2
et vous utilisez v14.0.2
installé via npm i graphql
. Rétrograder graphql
à v0.13.2
.
J'ai utilisé ID
et cela fonctionne bien! la cause de votre problème n'est pas du type id! c'est parce que vous lui donnez une mauvaise valeur: ObjectID('actuall id')
Pour résoudre ce problème, appelez la fonction toJson
pour chaque donnée extraite ou ajoutez simplement une variable virtuelle id
comme ceci:
YourSchema.virtual('id').get(function() {
return this.toJSON()._id
}
Donc, ce que je viens de découvrir, c'est que _id
est de type ObjectID
mais semble implicitement transtypé en String
. Donc, si vous définissez votre type d'identifiant de modèle mangouste sur String
au lieu de mongoose.Schema.Types.ObjectId
, il devrait alors fonctionner. En utilisant votre code actuel (tiré du tutoriel compose.com) qui copie _id en id, le résultat sera que, en mongo (après la sauvegarde), le _id sera de type ObjectID
et votre modèle ID de type chaîne.
En d'autres termes, au lieu de cela
const Account = mongoose.model('Account', new mongoose.Schema({
id: mongoose.Schema.Types.ObjectId,
name: String
}));
Faire ceci
const Account = mongoose.model('Account', new mongoose.Schema({
id: String,
name: String
}));