Не удалось запросить поле \ "addWorkout \" для типа \ "Мутация \" - PullRequest
0 голосов
/ 16 февраля 2020

Я довольно новичок в GraphQL, мой предыдущий вопрос касался какой-то ссылочной ошибки, которую я получал, но которую я в итоге исправил, однако теперь я получаю эту ошибку. Кажется, я не могу добавить тренировку, так как она не распознает, что это поле мутации в схеме.

Я получаю сообщение об ошибке

Cannot query field \"addWorkout\" on type \"Mutation\

В любом случае, в приложении. js, это мой код

const express = require("express")
const app = express();
const userSchema = require("./graph-schema/userQueries")
const workoutSchema = require("./graph-schema/workoutQueries")
const mealSchema = require("./graph-schema/mealQueries")
const mongoose = require("mongoose")
const {mergeSchemas} = require("graphql-tools")

//connect to mongoDB atlase database
mongoose.connect("mongodb+srv://Zubair97:superman2008@cluster0-epauj.mongodb.net/test?retryWrites=true&w=majority")
mongoose.connection.once("open", () => {
    console.log("Connected to database")
})

const combinedSchemas = mergeSchemas({
    schemas: [
        userSchema,
        mealSchema,
        workoutSchema
    ],
})




//this module allows express to communicate with graphql ;
//we use it as a single endpoint
const graphqlHTTP = require("express-graphql")

app.use("/graphql" , graphqlHTTP({
    schema: combinedSchemas,
    graphiql: true


}))


app.listen(4000, () => {
    console.log(`Listening on port 4000`)
})

Определяются запросы на тренировки и мутации в файле с именем workoutQueries. js, который я экспортировал, вы можете видеть, что у меня есть addWorkout, определенный в резольверах

const graphql = require("graphql")
const {WorkoutType} = require("./schema")
const Workout = require("../models/Workout.js")
const {GraphQLObjectType, GraphQLID, GraphQLString, GraphQLSchema, GraphQLInt, GraphQLList} = graphql;

const WorkoutQuery = new GraphQLObjectType({
    name: "WorkoutQuery",
    fields: () => ({
        workout: {
            type: WorkoutType,
            args: {id: {type: GraphQLID}},
            resolve(parent, args){
                //returns the workout instance from the database
                return Workout.findById(args.id)
            }

        },

        workouts: {
            type: new GraphQLList(WorkoutType),
            resolve(parent, args){
                //returns all workouts from the databse
                return Workout.find({})
            }
        }
    })

})

const WorkoutMutation = new GraphQLObjectType({
    name: "WorkoutMutation",
    addWorkout: {
        type: WorkoutType,
        args: {
            name: {type: GraphQLString},
            reps: {type: GraphQLInt},
            sets: {type: GraphQLInt},
            burnedCalories: {type: GraphQLInt},
            userId: {type: GraphQLID},

        },
        resolve(parent, args){
            let workout = new Workout({
                name: args.name,
                reps: args.reps,
                sets: args.sets,
                burnedCalories: args.burnedCalories,
                userId: args.userId
            })

            return workout.save();
        }
    },

})

module.exports = new GraphQLSchema({
    query: WorkoutQuery,
    mutation: WorkoutMutation
})

Кроме того, эта проблема возникает, даже если я пытаюсь добавить еду, запросы и мутации определены в файле с именем foodQueries. js, который я экспортировал

const graphql = require("graphql")
const {MealType, NutritionType} = require("./schema")
const Meal = require("../models/Meal.js")
const {GraphQLObjectType, GraphQLID, GraphQLString, GraphQLSchema, GraphQLInt, GraphQLList} = graphql;

const MealQuery = new GraphQLObjectType({
    name: "MealQueries",
    fields: () => ({
        meal: {
            type: MealType,
            args: {id: {type: GraphQLID}},
            resolve(parent, args){
                return Meal.findById(args.id)
            }
        },

        meals: {
            type: new GraphQLList(MealType),
            resolve(parent, args){
                return Meal.find({})
            }
        }

    })

})

const MealMutation = new GraphQLObjectType({
    name: "MealMutation",
    addMeal: {
        type: MealType,
        args: {
            name: {type: GraphQLString},
            servings: {type: GraphQLInt},
            calories: {type: GraphQLInt},
            nutrition: {type: NutritionType},
            userId: {type: GraphQLID}
        },
        resolve(parent, args){

            let meal = new Meal({
                userId: args.userId,
                name: args.name,
                servings: args.servings,
                calories: args.calories,
                nutrition: {
                    carbohydrates: args.nutrition.carbohydrates,
                    fats: args.nutrition.fats,
                    proteins: args.nutrition.proteins
                }
            })

            return meal.save();
        }
    }

})

module.exports = new GraphQLSchema({
    query: MealQuery,
    mutation: MealMutation
})

У меня нет проблем при создании пользователя и аутентификации пользователя, запросы и мутации для этого определены в userQueries. js

const graphql = require("graphql")
const User = require("../models/User.js")
const bcrypt = require("bcrypt")
const jwt = require("jsonwebtoken")
const {AuthType, UserType} = require("./schema")
const {GraphQLObjectType, GraphQLID, GraphQLString, GraphQLSchema, GraphQLInt, GraphQLList} = graphql;


const UserQuery = new GraphQLObjectType({
    name: "UserQuery",
    fields: () => ({
        user: {
            type: UserType,
            args: {id: {type: GraphQLID}},
            resolve(parent, args){
                //returns the user from the database
                return User.findById(args.id)
            }
        },
        login: {
            type: AuthType,
            args: {email: {type: GraphQLString}, password: {type: GraphQLString}},
            resolve(parent, {email, password}){
                return User.findOne({email: email}).then((user) => {
                    const isEqual = bcrypt.compare(password, user.password)
                    if (!isEqual) {
                        throw new Error('Password is incorrect!');
                    }

                    const token = jwt.sign({
                        userId: user.id,
                        email: user.email},
                        "a_super_secret",
                        {expiresIn: "1h"}
                    )

                    return {token: token, userId: user.id}


                })

            }
        }


    })


})



const UserMutation = new GraphQLObjectType({
    name: "Mutation",
    fields: {
        addUser: {
            type: UserType,
            args: {
                name: {type: GraphQLString},
                email: {type: GraphQLString},
                password: {type: GraphQLString}
            },
            async resolve(parent, args){
                const existingUser =  await User.findOne({email: args.email})
                if (!existingUser){
                    const error = new Error("User already exists");
                }

                const encryptedPassword =  await bcrypt.hash(args.password, 12)

                let user = new User({
                    name: args.name,
                    email: args.email,
                    password: encryptedPassword
                })

                const createdUser =  user.save();
                return createdUser
            }
        }



    }
})


module.exports = new GraphQLSchema({
    query: UserQuery,
    mutation: UserMutation,
})

Я также определил UserType, AuthType, MealType, NutritionType и WorkoutType в файле с именем schema. js

const graphql = require("graphql")
const Workout = require("../models/Workout.js")
const User = require("../models/User.js")
const Meal = require("../models/Meal")

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

//describes what attributes and its types, a User has in each query
const UserType = new GraphQLObjectType({
    name: "User",
    fields: () => ({
        id: {type: GraphQLID},
        name: {type: GraphQLString},
        email: {type: GraphQLString},
        password: {type: GraphQLString},
        workouts: {
            type: new GraphQLList(WorkoutType),
            resolve(parent, args){
                //returns all the workouts created by a user
                return Workout.findById({userId: parent.id})
            }
        },
        meals: {
            type: new GraphQLList(MealType),
            resolve(parent, args){
                //returns all the meals created by a user
                return Meal.findById({userId: parent.id})
            }
        }

    })
})

const NutritionType = new GraphQLObjectType({
    name: "Nutrition",
    fields: () => ({
        carbohydrates: {type: GraphQLInt},
        fats: {type: GraphQLInt},
        proteins: {type: GraphQLInt}
    })
})



const WorkoutType = new GraphQLObjectType({
    name: "Workout",
    fields: () => ({
        id: {type: GraphQLID},
        name: {type: GraphQLString},
        reps: {type: GraphQLInt},
        burnedCalories: {type: GraphQLInt},
        sets: {type: GraphQLInt},
        user: {
            type: UserType,
            resolve(parent, args){
                //returns the user from the database that created the workout instance
                return User.findById(parent.userId)

            }
        }

    })
})




const AuthType = new GraphQLObjectType({
    name: "Authentication",
    fields: () => ({
        token: {type: GraphQLString},
        userId: {type: GraphQLString}
    })
})



const MealType = new GraphQLObjectType({
    name: "Meal",
    fields: () => ({
        id: {type: GraphQLID},
        calories: {type: GraphQLInt},
        servings: {type: GraphQLInt},
        nutrition: {type: NutritionType},
        user: {
            type: UserType,
            resolve(parent, args){
                //returns the user from the database that created the meal instance
                return User.findById(parent.userId)
            }
        }

    })
})




module.exports = {
    AuthType,
    WorkoutType,
    UserType,
    MealType,
    NutritionType
}

Я подозреваю, что Я получаю ошибку из-за объекта mergeSchema из graphql-tools, может быть, он не может правильно слить типы GraphQLSchema? Я не уверена. Любая помощь приветствуется!

1 Ответ

0 голосов
/ 16 февраля 2020

mergeSchemas предназначен для использования с схемной вышивкой . Он не должен использоваться только для модульной схемы. Это то, что вы пытаетесь сделать здесь.

Вы должны создать только один GraphQLSchema объект, один GraphQLObjectType для вашего запроса root тип и один GraphQLObjectType для вашей мутации root тип. Если вы хотите, чтобы поля для указанного типа c, такого как ваш тип Mutation, были распределены по нескольким модулям, вам следует экспортировать только эти поля , а не весь тип или схему.

module.exports = {
  queries: {
    workout: { ... },
    workouts: { ... },
  },
  mutations: {
    addWorkout: { ... },
  },
}

В любом файле, в котором вы создаете свою схему, можно импортировать эти поля из нескольких модулей и объединить их в отдельную схему.

const query = new GraphQLObjectType({
  name: 'Query',
  fields: () => ({
    ...require('moduleA').queries,
    ...require('moduleB').queries,
    ...require('moduleC').queries,
  }),
})
const mutation = new GraphQLObjectType({ ... })
const schema = new GraphQLSchema({ query, mutation })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...