
本文详解因 GraphQL 变量类型声明与实际传入值不一致(如 schema 要求 Int,但 query 声明为 String!,而客户端传入数字),导致 Apollo 请求在解析阶段失败、返回 HTTP 400 状态码且 resolver 根本未执行的问题。
本文详解因 graphql 变量类型声明与实际传入值不一致(如 schema 要求 `int`,但 query 声明为 `string!`,而客户端传入数字),导致 apollo 请求在解析阶段失败、返回 http 400 状态码且 resolver 根本未执行的问题。
在使用 Apollo Client 调用 GraphQL 接口时,若遇到 ApolloError: Response not successful: Received status code 400,且服务端 resolver 完全未被触发(例如 console.log(args) 无输出),这通常意味着请求甚至未能通过 GraphQL 层的请求验证——错误发生在 Apollo Server 的解析(parsing)或验证(validation)阶段,而非业务逻辑执行阶段。
根本原因在于:客户端传递的变量类型与 GraphQL Schema 中定义的参数类型不兼容。观察你提供的代码:
-
schema.js中,accountID参数明确声明为new GraphQLNonNull(GraphQLInt)→ 即必须为 整数(Int); -
queries.js中,却将变量$accountID声明为String!→ 即期望传入字符串; -
SavingsDashboard.js中,useQuery实际传入的是accountID: 1(JavaScript 数字)。
这构成了三重不一致:
- Schema 要求
Int - Query 变量定义为
String! - 实际值是 JS
number(非字符串)
GraphQL 规范要求:变量类型必须严格匹配 schema 中定义的输入类型。当 Apollo Server 尝试将变量 accountID: 1(数字)绑定到类型为 String! 的变量时,类型校验失败,直接返回 400 Bad Request,并附带类似 "Variable '$accountID' of type 'String!' used in position expecting type 'Int!'" 的错误信息(可通过开启 Apollo Server 的 debug: true 查看完整响应体)。
✅ 正确做法是保持三者统一。推荐采用以下修正方案:
1. 修改 queries.js —— 使变量类型与 Schema 一致:
import { gql } from '@apollo/client';
const GET_DATA = gql`
query GetData($accountID: Int!, $auth: String!) {
data(accountID: $accountID, auth: $auth) {
id
name
}
}
`;
export { GET_DATA };2. 确保 schema.js 定义清晰(你已正确):
accountID: { type: new GraphQLNonNull(GraphQLInt) }, // ✅ 期望 Int3. 客户端传值无需强制转字符串(1 是合法的 Int):
const { loading, error, data } = useQuery(GET_DATA, {
variables: {
accountID: 1, // ✅ 数字 1 可直接作为 GraphQL Int 传递
auth: "test" // ✅ 字符串保持不变
}
});⚠️ 注意事项:
- 不要为了“匹配 String 类型”而在前端写
accountID: String(1)或"1",否则会与 schema 的GraphQLInt冲突; - Apollo Client 会自动将 JavaScript
number序列化为 GraphQLInt,前提是 query 中变量类型声明为Int!; - 若后端数据库实际需要字符串 ID(如 MongoDB ObjectId),应在 resolver 内部做类型转换(如
args.accountID.toString()),而非在 schema 层妥协类型定义; - 开发时建议启用 Apollo Server 的调试模式(
new ApolloServer({ ..., debug: true })),便于快速定位此类类型不匹配错误。
总结:GraphQL 的强类型特性要求前端 query、后端 schema 和运行时变量值三者严格对齐。HTTP 400 往往是类型失配的第一信号,优先检查 gql 中的变量类型声明是否与 GraphQLObjectType.args 定义完全一致,即可高效排除此类问题。

















