使用graphql-request请求报Variable `userId` is required错误如何解决
问题背景
- 调用其他独立GraphQL端点时,使用graphql-request包发起请求,应用内其余GraphQL交互均通过React侧集成的Apollo Client完成
- 业务逻辑规则:用户未登录时,存储的用户
id值为null;用户登录后,id为字符串类型值,通过Apollo Client提供的useReactiveVar读取用户ID的逻辑运行正常 - 编写的接口调用代码如下:
const endpoint = 'https://my-endpoint/graphql'; const query = gql` query($userId: String!) { isEligible(userId: $userId) } `; const variables = { userId: id, }; request(endpoint, query, variables).then((data2) => console.log(data2));
- 调用接口时抛出如下错误:
ClientError: Variable
userIdis required.:
{"response":{"errors":[{"message":"VariableuserIdis required.
故障原因
查询语句中把$userId参数定义为了非空类型String!,GraphQL服务端校验规则要求该类型参数不能接收null或undefined值。未登录场景下id本身值为null,如果此时触发请求,就会直接触发参数校验报错;如果组件初始化阶段id还未完成赋值(值为undefined)就提前发起请求,也会抛出同样的错误。
修复方案
根据业务需求二选一处理即可:
- 方案1:增加请求触发的前置校验,只有拿到有效字符串格式的用户ID时才发起请求,未登录状态下直接跳过该接口调用,走未登录对应的默认业务逻辑
参考实现:// 校验id为有效字符串时才执行请求 if (typeof id === 'string' && id.trim()) { const variables = { userId: id }; request(endpoint, query, variables).then((data2) => console.log(data2)); } else { // 自定义未登录场景逻辑,比如设置默认的资格校验结果 console.log('用户未登录,跳过资格查询'); } - 方案2:如果业务要求未登录状态下也需要调用该接口,先和后端对齐空值传参的处理规则,再把查询中参数的非空约束去掉,改为可空类型
String
修改后的查询定义:query($userId: String) { isEligible(userId: $userId) }
注意:不要为了绕过校验硬传空字符串,必须和后端确认空值的业务语义,避免出现权限判断、资格校验的逻辑异常。
内容的提问来源于stack exchange,提问作者meez
相关产品推荐
相关产品推荐

