GraphQL Mutation addUser无法创建用户问题排查求助
问题根因与修复方案
你遇到的请求未进入resolver等问题全部由以下可复现的语法/逻辑错误导致,按优先级修复即可:
1. resolvers.js 结构错误(核心原因,直接导致Mutation未注册)
你当前的Mutation配置块写在了resolvers对象的闭合大括号外面,属于未挂载的无效代码,GraphQL服务根本识别不到addUser resolver。
修复方案:把整个Mutation块移到resolvers对象内部:
const { User, Book } = require("../models"); const { AuthenticationError } = require("apollo-server-express"); const { signToken } = require("../utils/auth"); const resolvers = { Query: { me: async (parent, args, context) => { if (context.user) { return User.findOne({ _id: context.user._id }).populate("books"); } throw new AuthenticationError("You need to log in"); }, }, // Mutation块移到resolvers对象内部 Mutation: { addUser: async (parent, args) => { // 先解构args获取参数,否则username等变量未定义 const { username, email, password } = args; console.log("resolver test", args); const user = await User.create({ username, email, password }); const token = signToken(user); return { token, user }; }, login: async (parent, { email, password }) => { // 给User.findOne加await const user = await User.findOne({ email }); if (!user) { throw new AuthenticationError("Invalid Login Credentials"); } // 把不存在的profile变量改为user const correctPw = await user.isCorrectPassword(password); if (!correctPw) { throw new AuthenticationError("Invalid Login Credentials"); } const token = signToken(user); return { token, user }; }, saveBook: async (parent, { bookData }, context) => { if (context.user) { return User.findOneAndUpdate( { _id: context.user._id }, { $addToSet: { savedBooks: bookData } }, { new: true } ); } throw new AuthenticationError("You need to log in"); }, deleteBook: async (parent, { bookId }, context) => { if (context.user) { return User.findOneAndUpdate( // 修正拼写错误contex→context { _id: context.user._id }, // 修正取值错误context.bookId→传入的bookId参数 { $pull: { savedBooks: { bookId: bookId } } }, { new: true } ); } throw new AuthenticationError("You need to log in"); }, } }; module.exports = resolvers;
2. 前端SignupForm.js 逻辑错误
Apollo Client的useMutation返回的结果不是原生Fetch的Response对象,没有ok属性,也不需要调用json()方法,返回数据直接挂载在data字段下:
const handleFormSubmit = async (event) => { event.preventDefault(); const form = event.currentTarget; if (form.checkValidity() === false) { event.preventDefault(); event.stopPropagation(); } try { const { data } = await addUser({ variables: { ...userFormData }, }); const { token, user } = data.addUser; console.log(user); Auth.login(token); } catch (err) { console.error(err); setShowAlert(true); } setUserFormData({ username: "", email: "", password: "", }); };
3. auth.js 中间件错误
中间件catch块引用了不存在的res变量,Apollo上下文中间件不需要返回响应,直接返回req即可:
authMiddleware: function ({ req }) { let token = req.query.token || req.headers.authorization || req.body.token; if (req.headers.authorization) { token = token.split(" ").pop().trim(); } if (!token) { return req; } try { const { data } = jwt.verify(token, secret, { maxAge: expiration }); req.user = data; } catch { console.log("Invalid token"); // 删除不存在的res返回逻辑 } return req; },
以上错误全部修复后,addUser Mutation即可正常触发,返回token完成自动登录。
内容的提问来源于stack exchange,提问作者Leland Cypress
相关产品推荐
相关产品推荐

