【问题标题】:How to make a mutation query for inserting a list of (Array) fields in GraphQL如何进行突变查询以在 GraphQL 中插入(数组)字段列表
【发布时间】:2015-11-25 02:08:06
【问题描述】:

最近我开始研究 GraphQL,我能够毫无问题地在平面模式中插入数据,但是当涉及到数据数组时,我遇到了类似的错误

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

Mongoose 架构:

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

【问题讨论】:

  • 我已经做了类似的事情(使用数组)并且它有效。你能分享你的架构吗?
  • 嗨,mfirry,我在帖子中添加了我的 Mongoose 和 GraphQL 模式。请检查他们并尽快给我答复。谢谢!!
  • 我还需要你定义AddEventMutationType
  • 请检查我的代码,我添加了突变类型。谢谢...
  • @mfirry 此示例有效,因为在您的 airports 突变定义中,type: new GraphQLList(GraphQLString)GraphQLListGraphQLString 已经是输入类型,但是当您创建像 @Mahesh 这样的自定义类型时,您需要如果您想在突变中使用它,请使用 GraphQLInputObjectType 创建它。请参阅下面的答案。

标签: node.js mongodb-query graphql


【解决方案1】:

我遇到了同样的问题 - 我不知道如何在输入定义中指定对象数组。所以对于那些想要看到“文本”模式解决方案的人来说:

type Book {
  title: String!
}

在您的输入类型中有一个书籍数组

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

您不能只在输入语句中添加books: [Book!],您需要特意创建包含所需字段的输入类型(如果您愿意,可以复制):

input BookInput {
  title: String!
}

然后你可以:

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

【讨论】:

    【解决方案2】:

    您的问题是,当您定义突变时,所有类型都必须是输入类型,因此您会得到"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 类型列表)。

    但是,您的类型 mediaTypelocationType 属于 GraphQLObjectType 类型,这不是输入类型,但如果您再次查看输入类型列表:https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82,您会发现 GraphQLInputObjectType 其中是一个对象输入类型,因此,您需要做的是将mediaTypelocationType 替换为它们的“输入”版本。

    我建议做的是创建mediaInputTypelocationInputType,它们将具有与mediaTypelocationType 相同的字段结构,但使用new GraphQLInputObjectType({... 而不是new GraphQLObjectType({... 创建并在您的突变中使用它们.

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

    【讨论】:

    猜你喜欢
    • 2022-11-25
    • 2022-06-23
    • 2020-07-05
    • 2020-01-03
    • 2021-03-16
    • 2019-04-04
    • 2021-12-21
    • 1970-01-01
    • 2018-09-17
    相关资源
    最近更新 更多