web-dev-qa-db-ja.com

GraphQLに(配列)フィールドのリストを挿入するための突然変異クエリを作成する方法

最近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);
                  });
            })
          });
       }
     }
22
Mahesh

あなたの問題は、ミューテーションを定義するとき、すべてのタイプが入力タイプでなければならないため、エラーが"Must be input type"を受け取ることです。だからここで(あなたの突然変異から):

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

GraphQLListmediaType、およびlocationTypeは入力タイプでなければなりません。

GraphQLListはすでに入力タイプです(こちらを参照してください https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82 入力タイプと見なされるGraphQLタイプのリストを参照してください)。

ただし、タイプmediaTypeおよびlocationTypeGraphQLObjectTypeタイプです。これは入力タイプではありませんが、入力タイプのリストをもう一度見ると、 https: //github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82 には、オブジェクト入力タイプであるGraphQLInputObjectTypeがあります。必要なことは、mediaTypelocationTypeを「入力」バージョンに置き換えることです。

私が行うことをお勧めするのは、mediaInputTypeおよびlocationInputTypeと同じフィールド構造を持つが、new GraphQLInputObjectType({...で作成されるmediaTypeおよびlocationTypeを作成することです。 new GraphQLObjectType({...の代わりに、ミューテーションで使用します。

私は同じ問題にぶつかり、そのように解決しました。質問があればコメントしてください。

22
adriantoine

同じ問題にぶつかりました-入力定義でオブジェクトの配列を指定する方法を知りませんでした。そのため、「テキスト」スキーマソリューションを確認したい場合:

type Book {
  title: String!
}

入力タイプに書籍の配列を含める

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

inputステートメント内にbooks: [Book!]を追加することはできません。必要なフィールドを含む入力タイプを意図的に作成する必要があります(必要に応じて複製します)。

input BookInput {
  title: String!
}

そして、次のことができます:

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