Как определить поле объекта в GraphQLObjectType? - PullRequest
0 голосов
/ 06 мая 2018

Поэтому я пытаюсь создать коллекцию User в MongoDB и выполнять запросы к ней, используя GraphQL и mongoose.

Я создал свою пользовательскую схему по пути pathToServer \ server \ models \ user.js, и она выглядит так:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
    name: {
        firstName: String,
        lastName: String,
    },
    email: String,
    password: String,
})

module.exports = mongoose.model('User', userSchema);

И я создал тип GraphQL, в настоящее время он находится по пути pathToServer \ server \ schema \ types \ user.js и выглядит так:

const graphql = require('graphql');

const {GraphQLObjectType, GraphQLList, GraphQLInt, GraphQLID, GraphQLString, GraphQLSchema, GraphQLNonNull} = graphql;

const UserType = new GraphQLObjectType({
    name: 'User',
    fields: () => ({
        id: {type: GraphQLID},
        email: {type: GraphQLString},
        name: new GraphQLObjectType({
            firstName: {type: GraphQLString},
            lastName: {type: GraphQLString}
        })
    })
});

module.exports = UserType;

Наконец, у меня есть схема GraphQL с запросами и мутацией в пути 'pathToServer \ server \ schema \ schema.js':

const graphql = require('graphql');

const {GraphQLObjectType, GraphQLList, GraphQLInt, GraphQLID, GraphQLString, GraphQLSchema, GraphQLNonNull} = graphql;

const User = require('../models/user');

const UserType = require('./types/user');

const RootQuery = new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
        user: {
            type: UserType,
            args: {
                id: {
                    type: GraphQLID
                }
            },
            resolve(parent, args){
                return User.findById(args.id);
            }
        },
        users: {
            type: new GraphQLList(UserType),
            resolve(parent, args){
                return User.find({})
            }
        }
    }
})

const Mutation = new GraphQLObjectType({
    name: 'Mutation',
    fields: {
        addUser: {
            type: UserType,
            args: {
                name: {
                    firstName: {type: new GraphQLNonNull(GraphQLString)},
                    lastName: {type: new GraphQLNonNull(GraphQLString)}
                },
                email: {type: new GraphQLNonNull(GraphQLString)},
                password: {type: new GraphQLNonNull(GraphQLString)}
            },
            resolve(parent, args){
                let user = new User({
                    name: args.name,
                    email: args.email,
                    password: args.password,
                });

                return user.save();
            }
        }
    }
})


module.exports = new GraphQLSchema({
    query: RootQuery,
    mutation: Mutation
})

Проблема в том, что при запуске сервера выдается ошибка:

Error: Must provide name.
    at invariant (pathToServer\server\node_modules\graphql\jsutils\invariant.js:19:11)
    at new GraphQLObjectType (pathToServer\server\node_modules\graphql\type\definition.js:499:66)
    at fields (pathToServer\server\schema\types\user.js:10:15)
    at resolveThunk (pathToServer\server\node_modules\graphql\type\definition.js:370:40)
    at defineFieldMap (pathToServer\server\node_modules\graphql\type\definition.js:532:18)
    at GraphQLObjectType.getFields (pathToServer\server\node_modules\graphql\type\definition.js:506:44)
    at typeMapReducer (pathToServer\server\node_modules\graphql\type\schema.js:232:38)
    at pathToServer\server\node_modules\graphql\type\schema.js:239:20
    at Array.forEach (<anonymous>)
    at typeMapReducer (pathToServer\server\node_modules\graphql\type\schema.js:232:51)
    at Array.reduce (<anonymous>)
    at new GraphQLSchema (pathToServer\server\node_modules\graphql\type\schema.js:122:28)
    at Object.<anonymous> (pathToServer\server\schema\schema.js:79:18)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)

Может быть, я не правильно определил поле имени? Я думаю, что это может рассматриваться по-разному, поскольку поле имени в моей модели является объектом, содержащим поля firstName и lastName.

Можете взглянуть, пожалуйста?

Заранее спасибо!

EDIT Я изменил тип пользователя с

const UserType = new GraphQLObjectType({
    name: 'User',
    fields: () => ({
        id: {type: GraphQLID},
        email: {type: GraphQLString},
        name: new GraphQLObjectType({
            firstName: {type: GraphQLString},
            lastName: {type: GraphQLString}
        })
    })
});

до

const UserType = new GraphQLObjectType({
    name: 'User',
    fields: () => ({
        id: {type: GraphQLID},
        email: {type: GraphQLString},
        name: {
            firstName: {type: GraphQLString},
            lastName: {type: GraphQLString}
        }
    })
});

Теперь сервер запускается, но он выдает мне эту ошибку в graphiql:

{
  "errors": [
    {
      "message": "The type of User.name must be Output Type but got: undefined.\n\nThe type of Mutation.addUser(name:) must be Input Type but got: undefined."
    }
  ]
}

1 Ответ

0 голосов
/ 06 мая 2018

Вы были на правильном пути с вашей первоначальной попыткой. Частично проблема заключается в том, что тип, который вы передаете в поле name вашего UserType, должен быть полностью определен. То есть ему нужно не только свойство fields, но и само свойство name. Другая проблема заключается в том, что User.name должен явно указывать свой тип как свойство. Для удобства чтения и повторного использования я бы сделал ваш NameType отдельной переменной:

const NameType = new graphQLObjectType({
  name: 'Name',
  fields: () => ({
    firstName: { type: GraphQLString },
    lastName: { type: GraphQLString },
  }),
})

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    id: { type: GraphQLID },
    email: { type: GraphQLString },
    name: { type: NameType }
  })
})
...