NestJS GraphQL 中Mutation/Query的Input DTO入参始终为空对象问题
NestJS GraphQL 入参始终为空的排查与解决方案
核心报错关联逻辑
当前触发的Cannot return null for non-nullable field Query.testMutation属于衍生报错:由于入参解析失败,args.postId取值为undefined,返回空值和接口定义的非空String返回值不匹配,触发GraphQL协议校验。解决入参解析问题后,该报错会自动消除。
分步排查方向
1. 核对GraphQL Playground的请求结构
这是占比最高的入参为空触发原因,需严格匹配Resolver定义的参数结构:
- 你的Resolver定义接口接收一个名为
args的入参,类型为对象UpvotePostInput,因此Playground中的查询语句必须符合对象传参规范:# 正确写法 query { testMutation(args: { postId: "test_value" }) } - 常见错误写法会导致参数解析为空对象:
- 直接把对象字段拆分为接口入参传入:
query { testMutation(postId: "test_value") } - 漏写
args层级的参数包装
- 直接把对象字段拆分为接口入参传入:
- 排查时可以先在Resolver逻辑的第一行直接打印
args,确认请求发送时服务端实际接收到的参数结构。
2. 检查全局管道的配置冲突
全局注册的ValidationPipe配置错误是第二大高频诱因:
- 若你在
main.ts中全局注册了校验管道,需确保开启transform: true配置——只有开启该配置,class-transformer才会将GraphQL传入的纯JS对象实例化为对应的DTO类,否则可能出现字段未映射的空对象。 - 若开启了
whitelist白名单校验,需确认DTO上的@Field、校验装饰器正确声明。白名单模式下管道会自动过滤所有未在DTO上声明的字段,配置不当时所有字段都会被清空,最终传入Resolver的就是空对象。 - 典型错误配置示例:
// 会导致入参被全量过滤的配置 app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, // 遗漏transform配置 }))
3. 核对GraphQL模块的Schema生成配置
NestJS的GraphQL schema自动生成逻辑异常会导致类型映射失效:
- 检查
GraphQLModule.forRoot()的配置项,确认autoSchemaFile已正确设置,保证@InputType、@Field装饰器能被扫描并生成对应的SDL schema。 - 若采用手动编写SDL的模式,需确认SDL中定义的
testMutation接口的入参结构和Resolver使用的UpvotePostInput完全匹配,字段名、可空性不一致会直接导致参数解析失败。 - 快速校验方式:打开GraphQL Playground的内置Schema文档,查看
testMutation接口的入参定义是否和代码中一致,若文档显示的入参结构缺失,说明类型扫描未生效。
4. 检查Resolver装饰器的映射关系
- 确认
@Args装饰器和方法入参的顺序一一对应:若方法中同时使用了@Ctx、@CurrentUser等自定义参数装饰器,错位排布会导致args对象被错误赋值。 - 检查是否存在自定义请求拦截中间件,提前修改了GraphQL的请求body结构,导致参数字段被过滤。
内容的提问来源于stack exchange,提问作者24sharon
相关产品推荐
相关产品推荐

