GraphQL创建用户Mutation返回400状态码求助
问题描述
在Apollo Sandbox/Studio中执行用户注册Mutation可正常完成,但通过浏览器前端发起相同请求时,返回状态码400,无法完成注册。已查阅官方文档及教程未找到原因,附上相关代码请求协助排查。
前端代码
const CREATE_USER_MUTATION = gql` mutation CreateUser($username: String!, $password: String!){ create_user(username: $username, password: $password){ username password } } ` const Register = () => { const [username, setUsername] = useState('') const [pass1, setPass1] = useState('') const [pass2, setPass2] = useState('') const [create_user, { data, loading, error }] = useMutation(CREATE_USER_MUTATION) const registerCheck = (e) => { e.preventDefault() if (pass1 == pass2) { create_user({ variables: { username: username, password: pass1 } }) } }
错误信息
Error: Response not successful: Received status code 400
后端Resolver代码
create_user: async (_parent, args, ctx) => { const result = await ctx.prisma.user.create({ data: { username: args.username, password: args.password } }) if (!result) return { success: false, message: "failed to create user" } if (result) { return { success: true, message: 'user created: ' + result.username, user: result } } }
后端Schema
type User { id: String name: String email: String username: String password: String image: String assigned_projects: [Project] } type Mutation { create_user(username: String!, password: String!): UserCreatedResponse }
排查关键点
返回类型不匹配:前端Mutation请求
create_user下的username和password字段,但后端Schema定义create_user返回UserCreatedResponse类型(而非User)。前端期望获取User结构,但实际返回的是包含success、message、user的对象,导致GraphQL查询解析失败,触发400错误。- 修正方式:要么修改前端Mutation,请求
UserCreatedResponse的合法字段,示例:mutation CreateUser($username: String!, $password: String!){ create_user(username: $username, password: $password){ success message user { username password } } } - 要么调整后端Schema,让
create_user返回User类型(但会丢失状态信息,需根据业务需求权衡)。
- 修正方式:要么修改前端Mutation,请求
异常捕获缺失:后端Resolver未捕获Prisma创建用户时可能抛出的异常(如用户名重复、字段验证失败),异常会导致返回格式不符合GraphQL规范,触发400错误。建议添加try-catch块:
create_user: async (_parent, args, ctx) => { try { const result = await ctx.prisma.user.create({ data: { username: args.username, password: args.password } }) return { success: true, message: 'user created: ' + result.username, user: result } } catch (err) { return { success: false, message: err.message || "failed to create user" } } }请求参数验证:在浏览器Network面板查看请求体,确认前端发送的变量
username和password是否正确传递(比如是否为空字符串,Sandbox可能手动输入了有效值,但前端表单可能未正确获取输入)。CORS与请求头检查:虽然Sandbox正常,但浏览器可能存在CORS配置问题,或前端Apollo Client未设置正确的请求头(如
Content-Type: application/json),可检查后端CORS配置及客户端请求头。
内容的提问来源于stack exchange,提问作者Sujio

