Как определить поле объекта в GraphQLObjectType?

Итак, я пытаюсь создать коллекцию пользователей в 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.

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

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

РЕДАКТИРОВАТЬ Я редактировал тип пользователя из

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."
    }
  ]
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
2 363
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В своей первоначальной попытке вы были на правильном пути. Отчасти проблема заключается в том, что тип, который вы передаете в поле 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 }
  })
})

Единственная проблема сейчас связана с мутацией. Я получил сообщение об ошибке: «Тип Mutation.addUser (name :) должен быть типом ввода, но получил: UserName». Означает ли это, что для аргумента имени мутации мне нужно создать отдельный тип GraphQL, но на этот раз вместо GraphQLObjectType использовать GraphQLInputObjectType. Это правильный подход?

alfaneo 06.05.2018 17:06

Да, GraphQLObjectType нельзя использовать для GraphQLInputObjectType и наоборот. Отметьте ответ как принятый, если вы сочли его полезным :)

Daniel Rearden 06.05.2018 18:06

Другие вопросы по теме