You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Apollo Client创建新用户时出现POST请求400错误

注册用户时POST 400错误排查与解决

问题现象

创建新用户时触发 POST http://localhost:4000/ 400(Bad Request) 错误,前端onError回调中的graphQLErrors未在控制台打印,但通过Apollo Studio运行同名Mutation却能正常执行。

网络响应明确提示:GraphQLError: Unknown argument "createUserInput" on field "Mutation.createUser"


相关代码

前端实现代码

const REGISTER_USER = gql`
    mutation Mutation(
        $createUser: CreateUserInput!
    ) {
        createUser(createUserInput: $createUserInput){
            email
            name
            token
            password
        }
    } 
`

const Register = () => {
    const context = useContext(AuthContext)
    let navigate = useNavigate()
    const [errors, setErrors] = useState([])

    function registerUserCallback() {
        console.log("Callback hit")
        registerUser()
    }

    const {onChange, onSubmit, values} = useForm(registerUserCallback, {
        name: '',
        email: '',
        password:'',
        confirmPassword: '',
    })

    const [registerUser, {loading}] = useMutation(REGISTER_USER, {
        update(proxy, {data: {registerUser: userData}}) {
            context.login(userData)
            navigate('/Dashboard')
        },
        onError({graphQLErrors}) {
            setErrors(graphQLErrors)
            console.log("Error: " + graphQLErrors)
            console.log(graphQLErrors)
        },
        variables: {createUserInput: values}
    })

Apollo Client配置代码

import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";
import { setContext } from "@apollo/client/link/context";

const httpLink = createHttpLink({
    uri: 'http://localhost:4000'
})

const authLink = setContext((_, {headers}) => {
    return {
        headers: {
            ...headers,
            authorization: localStorage.getItem('token') || ""
        }
    }
})
export const client = new ApolloClient({
    link: authLink.concat(httpLink),
    cache: new InMemoryCache()
});

后端Mutation代码

@Mutation((returns) => User)
async createUser(@Arg('data') data:CreateUserInput, @Ctx() ctx: Context) {
    const oldUser = await ctx.prisma.user.findFirst({ where: { email: data.email}})
    if(oldUser) {
        throw new ApolloError('A user is already registered with the email' + data.email, 'USER_ALREADY_EXISTS')
    }
    var encryptedPassword = await bcrypt.hash(data.password, 10)
    const newUser = await ctx.prisma.user.create({
        data: {
            name: data.name,
            email: data.email,
            password: encryptedPassword
        }
    })
    return {token: jwt.sign(newUser, 'supersecret')}
}

CreateUserInput代码

export class CreateUserInput {
    @Field((type) => String)
    name: string

    @Field((type) => String)
    email: string

    @Field((type) => String)
    password: string
}

问题根源

  1. 参数名不匹配:后端Mutation声明接收的参数名为data,但前端GraphQL请求中使用了createUserInput作为参数名,导致服务端无法识别参数
  2. 变量定义与传递不一致:前端Mutation中声明的变量是$createUser,但调用时传递的变量是createUserInput: values
  3. 返回字段不匹配:前端请求了password字段,但后端并未返回该字段
  4. update回调字段错误:前端update函数中使用registerUser获取返回数据,但后端Mutation的字段名是createUser

修复步骤

1. 修正前端GraphQL Mutation定义

将参数名改为data,去掉不存在的password请求字段:

const REGISTER_USER = gql`
    mutation Mutation(
        $data: CreateUserInput!
    ) {
        createUser(data: $data){
            email
            name
            token
        }
    } 
`

2. 修正useMutation配置

  • 对齐变量名与Mutation定义
  • 修正update回调的字段名
  • 过滤掉后端不需要的confirmPassword字段:
const [registerUser, {loading}] = useMutation(REGISTER_USER, {
    update(proxy, {data: {createUser: userData}}) {
        context.login(userData)
        navigate('/Dashboard')
    },
    onError(error) {
        // 打印完整错误信息便于排查
        console.log("Full error: ", error)
        setErrors(error.graphQLErrors || [])
    },
    variables: {
        data: {
            name: values.name,
            email: values.email,
            password: values.password
        }
    }
})

内容的提问来源于stack exchange,提问作者Esore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 01:18:27