GraphQL mutation省略可选字段roleId触发Bad Request错误咨询
问题根因
这个报错和GraphQL Schema的字段可选标记无关,问题出在后端的运行时入参校验逻辑:
大部分Node.js栈的GraphQL服务(比如NestJS的Code First模式实现),会在GraphQL自带的参数解析层之外,额外用class-validator这类工具做业务层参数校验。你虽然在Schema里标记roleId为可选字段,这一层规则只会让GraphQL网关不强制要求前端传该字段,但后端对应的校验DTO类里,roleId字段只配置了字符串类型校验规则,没有显式声明该字段可缺省。
当前端不传roleId时,解析后的入参里roleId值为undefined,校验逻辑判定undefined不是字符串类型,就会抛出roleId must be a string的400错误;显式传入字符串格式的roleId时符合校验规则,请求就能正常执行。
修复方式
- 后端修复:在
CustomerUpdateInput对应的校验DTO中,给roleId属性加上@IsOptional()装饰器,声明该字段可缺省,校验逻辑会自动跳过未传值时的类型检查。 - 临时规避:如果暂时无法修改后端代码,前端发起请求时不要省略
roleId字段,不需要修改该字段值的话,提前查询拿到当前已有的roleId原值随请求一起提交即可。
注:你提供的两段Mutation示例中,
updateCustomer参数闭合括号后多了一个多余的逗号,属于GraphQL语法错误,实际运行时需要删除,不过该语法问题不是触发本次参数校验报错的原因。
问题复现参考信息
Schema定义
input CustomerUpdateInput { name: String roleId: String } updateCustomer(customerId: String!, customer: CustomerUpdateInput!): Customer!
触发报错的Mutation
mutation updateCustomer{ updateCustomer(customerId:"62c6d6ba303c734ef44ea4ed", customer: {name:"Pablo"} ), {id, name } }
正常执行的Mutation
mutation updateCustomer{ updateCustomer(customerId:"62c6d6ba303c734ef44ea4ed", customer: { name:"Pablo", roleId:"62c6d64f303c734ef44ea4d8" } ), {id, name } }
返回的错误响应
{ "errors": [ { "message": "Bad Request Exception", "extensions": { "code": "BAD_USER_INPUT", "response": { "statusCode": 400, "message": [ "roleId must be a string" ], "error": "Bad Request" } } } ], "data": null }
内容的提问来源于stack exchange,提问作者g_m
相关产品推荐
相关产品推荐

