récemment j'ai commencé à travailler sur GraphQL, je suis capable d'insérer des données dans un schéma plat sans aucun problème mais quand il s'agit d'un tableau de données, je reçois une erreur comme
{ "errors": [ { "message": "Must be input type" } ]}
Je teste ma requête à l'aide de postman, ma requête de mutation est
mutation M {
AddEvent
(
title: "Birthday event"
description:"Welcome to all"
media:[{url:"www.google.com", mediaType:"image" }]
location:[{address:{state:"***", city:"****"}}]
)
{title,description,media,location,created,_id}}
Voici mon schéma d'événement:
EventType = new GraphQLObjectType({
name: 'Event',
description: 'A Event',
fields: () => ({
_id: {
type: GraphQLString,
description: 'The id of the event.',
},
id: {
type: GraphQLString,
description: 'The id of the event.',
},
title: {
type: GraphQLString,
description: 'The title of the event.',
},
description: {
type: GraphQLString,
description: 'The description of the event.',
},
media:{
type:new GraphQLList(mediaType),
description:'List of media',
},
location:{
type:new GraphQLList(locationType),
description:'List of location',
}
})
});
// Media Type
export var mediaType = new GraphQLObjectType({
name: 'Media',
description: 'A Media',
fields: () => ({
_id: {
type: GraphQLString,
description: 'The id of the event.',
},
url:{
type: GraphQLString,
description: 'The url of the event.',
},
mediaType:{
type: GraphQLString,
description: 'The mediaTypa of the event.',
}
})
});
// Location Type
export var locationType = new GraphQLObjectType({
name: 'Location',
description: 'A location',
fields: () => ({
_id: {
type: GraphQLString,
description: 'The id of the event.',
},
address:{
type: GraphQLString,
description: 'The address.',
},
state:{
type: GraphQLString,
description: 'The state.',
},
city:{
type: GraphQLString,
description: 'The city.',
},
Zip:{
type: GraphQLString,
description: 'The Zip code.',
},
country:{
type: GraphQLString,
description: 'The country.',
}
})
});
Schéma de mangouste:
var EventSchema = new mongoose.Schema({
title: {
required: true,
type: String,
trim: true,
match: /^([\w ,.!?]{1,100})$/
},
description: {
required: false,
type: String,
trim: true,
match: /^([\w ,.!?]{1,100})$/
},
media: [{
url: {
type: String,
trim: true
},
mediaType: {
type: String,
trim: true
}
}],
location: [{
address: {
type: String
},
city: {
type: String
},
state: {
type: String
},
Zip: {
type: String
},
country: {
type: String
}
}]
})
Type de mutation:
addEvent: {
type: EventType,
args: {
_id: {
type: GraphQLString,
description: 'The id of the event.',
},
title: {
type: GraphQLString,
description: 'The title of the event.',
},
description: {
type: GraphQLString,
description: 'The description of the event.',
},
media:{
type:new GraphQLList(mediaType),
description:'List of media',
},
location:{
type:new GraphQLList(locationType),
description:'List of media',
},
created: {
type: GraphQLInt,
description: 'The created of the user.',
}
},
resolve: (obj, {title,description,media,location,created,_id}) => {
let toCreateEvent = {
title,
description,
created:new Date(),
start: new Date(),
media,
location,
_id,
};
return mongo()
.then(db => {
return new Promise(
function(resolve,reject){
let collection = db.collection('events');
collection.insert(toCreateEvent, (err, result) => {
db.close();
if (err) {
reject(err);
return;
}
resolve(result);
});
})
});
}
}
Votre problème est que lorsque vous définissez des mutations, tous les types doivent être des types d'entrée, d'où l'erreur que vous obtenez "Must be input type"
. Donc ici (à partir de votre mutation):
media:{
type:new GraphQLList(mediaType),
description:'List of media',
},
location:{
type:new GraphQLList(locationType),
description:'List of media',
},
GraphQLList
, mediaType
et locationType
doivent être des types d'entrée.
GraphQLList
est déjà un type d'entrée (voir ici https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82 pour voir la liste des types GraphQL considérés comme types d'entrée).
Cependant, vos types mediaType
et locationType
sont de type GraphQLObjectType
, qui n'est pas un type d'entrée mais si vous regardez à nouveau la liste des types d'entrée: https: //github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82 , vous trouverez GraphQLInputObjectType
qui est un type d'entrée d'objet, donc, ce que vous devez faire est de remplacer mediaType
et locationType
par leur version "input".
Ce que je suggère de faire est de créer mediaInputType
et locationInputType
qui aurait la même structure de champ que mediaType
et locationType
mais créé avec new GraphQLInputObjectType({...
au lieu de new GraphQLObjectType({...
et utilisez-les dans votre mutation.
J'ai rencontré le même problème et je l'ai résolu comme ça, n'hésitez pas à commenter si vous avez des questions.
J'ai rencontré le même problème - je ne savais pas comment spécifier un tableau d'objets dans la définition d'entrée. Donc, pour ceux qui veulent voir une solution de schéma "texte":
type Book {
title: String!
}
d'avoir un tableau de livres dans votre type d'entrée
input AuthorInput {
name: String!
age: Int!
}
vous ne pouvez pas simplement ajouter books: [Book!]
à l'intérieur de l'instruction d'entrée, vous aurez besoin de créer délibérément un type d'entrée contenant les champs nécessaires (dupliquez si vous le souhaitez):
input BookInput {
title: String!
}
et puis vous pouvez:
input AuthorInput {
name: String!
age: Int!
books: [BookInput!]
}