NestJS中@Body()与@Body('email')的区别及报错原因解析
问题解析:NestJS中@Body()与@Body('email')的差异导致Redis参数错误
场景还原
你在使用NestJS开发时,Auth Service的emailSender方法要求接收string类型的email参数:
async emailSender(email: string) { const vericode = this.generateOTP(); await this.cacheManager.set(email, vericode); await this.emailService.sendMail({ to: email, subject: `verification code`, text: `verification code is ${vericode}`, }); return 'success'; }
最初的Auth Controller代码是这样的:
@Post('/email/send') async emailSend(@Body() email: string) { return this.authService.emailSender(email); }
这时候会触发Redis的参数错误:
ERROR [ExceptionsHandler] node_redis: The SETEX command contains a invalid argument type. Only strings, dates and buffers are accepted. Please update your code to use valid argument types.Error: node_redis: The SETEX command contains a invalid argument type.
但把@Body()改成@Body('email')后,错误就消失了。
原因分析
- 当使用
@Body()时,NestJS会把整个请求体对象(比如前端传的{email: "user@example.com"})赋值给你声明的email变量。虽然你用TypeScript标注了email: string,但这只是编译时的类型提示,运行时email实际是一个对象。 - Redis的
SET命令要求键(key)必须是字符串、日期或缓冲区类型,传入对象自然会触发参数类型错误。 - 改成
@Body('email')后,NestJS会从请求体对象中提取email字段对应的值(也就是前端传的字符串),这时候传给emailSender的是真正的字符串类型,符合Redis的参数要求,错误也就消失了。
补充提醒
如果需要接收多个参数,更规范的做法是定义一个DTO类,比如:
class SendEmailDto { email: string; }
然后在控制器中使用:
@Post('/email/send') async emailSend(@Body() dto: SendEmailDto) { return this.authService.emailSender(dto.email); }
这样既能通过TypeScript做类型校验,也能明确获取请求体中的字段。
内容的提问来源于stack exchange,提问作者GGT
相关产品推荐
相关产品推荐

