如何在GraphQL中插入(Array)字段列表的突变查询

问题描述:

最近我开始研究GraphQL,我能够在没有任何问题的情况下在平面模式中插入数据,但是当涉及到数组Array越来越像如何在GraphQL中插入(Array)字段列表的突变查询

{ "errors": [ { "message": "Must be input type" } ]} 

我使用邮递员测试我的查询时出现错误,我的突变查询

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}} 

这是我的事件模式:

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.', 
    } 
    }) 
}); 

猫鼬架构:

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 
      } 
    }] 
}) 

突变类型:

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); 
        }); 
      }) 
      }); 
     } 
    } 
+0

我做了类似的事情(使用数组),它的工作原理。你能分享你的模式吗? – mfirry

+0

喂mfirry,我添加了我的Mongoose和GraphQL模式到帖子。请检查他们,并尽快给我答复。谢谢!! – Mahesh

+0

我还需要'MutationType'来定义'AddEvent' – mfirry

你的问题是,当你定义的突变,所有类型必须输入类型,因此你"Must be input type"错误。因此,在这里(从突变):

media:{ 
    type:new GraphQLList(mediaType), 
    description:'List of media', 
}, 
location:{ 
    type:new GraphQLList(locationType), 
    description:'List of media', 
}, 

GraphQLListmediaTypelocationType必须输入类型。

GraphQLList已经是输入类型(请参阅https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82以查看被视为输入类型的GraphQL类型列表)。

但是你的类型mediaTypelocationTypeGraphQLObjectType类型,这是不是输入型的,但如果你在输入类型的列表再看看:https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82,你会发现GraphQLInputObjectType这是一个对象输入类型,那么,是什么您需要做的是用其“输入”版本替换mediaTypelocationType

我的建议做的是创造mediaInputTypelocationInputType这将有相同的字段结构mediaTypelocationTypenew GraphQLInputObjectType({...代替new GraphQLObjectType({...创建并在突变中使用它们。

我遇到了同样的问题,我解决了这个问题,如果您有任何问题,请随时发表评论。

+0

这真棒,但它似乎并没有为我工作..我做错了什么?继承人我的突变类型 https://gist.github.com/piq9117/64cee784677915edc1da8ffec7ffa383 – ken

我遇到了同样的问题 - 我不知道如何在输入定义中指定对象数组。因此,对于那些谁愿意看到一个“文本”模式的解决方案:

type Book { 
    title: String! 
} 

有书籍的阵列,您输入型

input AuthorInput { 
    name: String! 
    age: Int! 
} 

你不能只是添加books: [Book!]输入语句中,你需要刻意创建包含所需的字段(重复的,如果你喜欢)输入类型:

input BookInput { 
    title: String! 
} 

,然后您可以:

input AuthorInput { 
    name: String! 
    age: Int! 
    books: [BookInput!] 
}