2015-08-31 8 views
19

Недавно я начал работать над GraphQL, я могу без проблем вставлять данные в плоскую схему, но когда дело доходит до массива данных, я получаю сообщение об ошибке, какКак сделать запрос на мутацию для вставки списка полей (Array) в 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); 
        }); 
      }) 
      }); 
     } 
    } 
+0

Я сделал что-то похожее на это (используя массивы), и он работает. Не могли бы вы поделиться своей схемой? – mfirry

+0

Привет, mfirry, я добавил свои схемы Mongoose и GraphQL к сообщению. Пожалуйста, проверьте их и дайте мне ответ как можно скорее. Спасибо!! – Mahesh

+0

Мне также нужен 'MutationType', в котором вы определяете' AddEvent' – mfirry

ответ

19

Ваш вопрос в том, что при определении мутаций, все типы должны быть входные типы, следовательно, ошибка вы получаете "Must be input type". Так что здесь (с вашей мутации):

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

GraphQLList, mediaType и locationType должны быть типы входов.

GraphQLList уже является типом ввода (см. Здесь https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82, чтобы просмотреть список типов GraphQL, рассматриваемых как типы ввода).

Однако ваши типы mediaType и locationType имеют GraphQLObjectType типа, который не является типом входа, но если вы посмотрите на список типов входных снова: https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82, вы найдете GraphQLInputObjectType, который является типом входного объекта, так, то вам нужно заменить mediaType и locationType на их «входную» версию.

То, что я предлагаю сделать, это создать mediaInputType и locationInputType, которая будет иметь ту же структуру поля как mediaType и locationType, но созданный с new GraphQLInputObjectType({... вместо new GraphQLObjectType({... и использовать их в своей мутации.

Я столкнулся с тем же вопросом, и я решил это так, не стесняйтесь комментировать, если у вас есть какие-либо вопросы.

+0

Это потрясающе, но, похоже, это не работает для меня. Что я делаю неправильно? Heres my mutationType https://gist.github.com/piq9117/64cee784677915edc1da8ffec7ffa383 – ken

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