Appearance
管道PIPE
管道pipe用于对控制器接收的数据进行验证或类型转换
内置管道
Nest
自带九个开箱即用的内置管道。
ValidationPipe
ParseIntPipe
ParseFloatPipe
ParseBoolPipe
ParseArrayPipe
ParseUUIDPipe
ParseEnumPipe
DefaultValuePipe
ParseFilePipe
声明方式
管道可以使用以下方式声明使用
控制器
控制器
@UsePipes(ValidationPipe)
export class UserController{
}
控制器方法
@UsePipes(ValidationPipe)
show()
方法参数
show(@param('id',ParseIntPipe))
模块
一般用于声明对模块全局影响的管道如表单验证
...
import { ValidatePipe } from './validate.pipe';
import { APP_PIPE } from '@nestjs/core';
@Module({
imports: [],
controllers: [AppController],
providers: [
AppService,
{
provide: APP_PIPE,
useClass: ValidatePipe,
},
],
})
export class AppModule {}
全局管道
一般用于声明对模块全局影响的管道如表单验证
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000, '0.0.0.0');
}
类型转换
使用管道可以对请求数据进行转换
常规方式
以下代码将报错,因为 findUnique 需要数值类型
import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get(':id')
show(@Param('id') id) {
return this.appService.users.findUnique({
where: { id },
});
}
}
我们可以改良下,将id强制转为数值
...
return this.appService.users.findUnique({
where: { id: +id },
});
..
使用管道
不过使用 ParseIntPipe 管道操作更推荐,它是专门做数据转换的
show(@Param('id', ParseIntPipe) id) {
return this.appService.users.findUnique({
where: { id },
});
}
也可以定义响应的状态码
@Get()
show(
@Query(
'id',
new ParseIntPipe({
errorHttpStatusCode: HttpStatus.BAD_REQUEST,
}),
)
id: number,
) {
return this.prisma.user.findUnique({
where: {
id,
},
});
}
也可以使用工厂函数自定义响应,下面是自定义响应消息
@Get()
show(
@Query(
'id',
new ParseIntPipe({
exceptionFactory: () => {
throw new BadRequestException('请传递数字');
},
}),
)
id: number,
) {
return this.prisma.user.findUnique({ where: { id } });
}
默认值管道
使用 DefaultValuePipe 管道用于定义默认值,下面示例表示,当没有 id 参数 时默认为1
@Get()
show(@Query('id', new DefaultValuePipe(1), ParseIntPipe) id: number) {
return this.prisma.users.findUnique({
where: { id },
});
}
自定义管道
如果系统提供的管道不够使用,你也可以自定义管道。
自定义管道也非常简单,使用下面命令将创建管道 custom.pipe.ts 用于对数据进行数值转换,即实现 ParseIntPipe 管道。
nest g pi custom
管道内容如下
import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class CustomPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
return metadata.metatype == Number ? +value : value;
}
}
下面以控制器方法 login(@Body('mobile', CustomPipe) mobile: number)
对metadata管道参数进行说明
选项 | 说明 |
---|---|
metatype | 参数类型:mobile:number ,metatype 为 number 构造函数 |
type | 参数类别: 如@Body、@Query |
data | 参数名称:@Body('mobile',CustomPipe),data为mobile |
然后就可以在控制器中使用管道了
import { Body, Controller, Post } from '@nestjs/common';
import { CustomPipe } from 'src/auth.pipe';
import { AuthService } from './auth.service';
@Controller()
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Post()
register() {
return 'register';
}
@Post('login')
login(@Body('mobile', CustomPipe) mobile: number) {
return mobile;
}
}