昨天学到接口,有接口就有验证,所以今天学管道和验证
DTO与数据验证
DTO:百度百科数据传输对象(Data Transfer Object),是一种设计模式之间传输数据的软件应用系统。我理解为是对数据进行验证的程序
pipe:管道是具有 @Injectable()
装饰器的类。管道应实现 PipeTransform
接口。
管道有两个典型的应用场景:
- 转换:管道将输入数据转换为所需的数据输出(例如,将字符串转换为整数)
- 验证:对输入数据进行验证,如果验证成功继续传递; 验证失败则抛出异常
总结下就是:在DTO中配置那些数据需要什么校验,在pipe中写校验和转换逻辑
官方推荐的校验器:class-validator
class-transformer
,我看package.json里面是有的,如果没安装下依赖
npm i --save class-validator class-transformer
class-validator是一个校验库,api很多(顺手把api贴在文章最后面了),但常用的就那几个,长度手机号非空之类的
在api还有个参数validationOptions上面文档没列出来,但在Validation messages中提到了,例如@Length
和@MaxLength
文档写的是`@Length(min: number, max?: number)
`和`@MaxLength(max: number)
`,实际可以这样配
@Length(10,20, {message: '长度在10到20之间'})
@MaxLength(8, {always: true, message: '长度不能超过$constraint1'})
ValidationOptions的配置项
each?: boolean;//验证项是否为数组
message?: string | ((validationArguments: ValidationArguments) => string);//报错信息
groups?: string[];//用于此验证的验证组。
always?: boolean;//是否始终必须始终执行验证
context?: any;
校验message中可获得的变量
$value - 正在验证的值
$property - 要验证的对象属性的名称
$target - 要验证的对象的类的名称
$constraint1, $constraint2, ... $constraintN - 由特定验证类型定义的约束
实操下,生成一个pipe验证管道
nest g pi modules/content/create-posts --no-spec --flat
把它改成这样,实现验证transform
import {
ArgumentMetadata,
HttpException,
HttpStatus,
Injectable,
PipeTransform,
} from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
@Injectable()
export class CreatePostsPipe implements PipeTransform {
/**
*
* @param value 告诉我们参数是一个 body @Body(),query @Query(),param @Param() 还是自定义参数
* @param metadata 参数的元类型
*/
async transform(value: any, metadata: ArgumentMetadata) {
// 实例化DTO
const Dto = plainToInstance(metadata.metatype, value);
const err = await validate(Dto);
if (err.length) {
// validate(Dto)返回一个报错的数组集合
console.log('err', err);
throw new HttpException(err, HttpStatus.BAD_REQUEST);
}
return value;
}
}
手动创建个dtos
// src/modules/content/dtos/create-post.dto.ts
import { Injectable } from '@nestjs/common';
import { MaxLength, IsNotEmpty, IsOptional, ArrayUnique } from 'class-validator';
@Injectable()
export class CreatePostsDto {
@ArrayUnique()
@MaxLength(8, {
always: true,
message: '长度不能超过$constraint1',
}) // 校验title最大长度
@IsNotEmpty({ message: '标题不能为空' }) // 校验title是否为空
title: string;
@IsNotEmpty({ message: '内容不能为空' }) // 校验body是否为空
body: string;
@MaxLength(500, {
always: true,
message: '长度不能超过$constraint1',
}) // 校验summary最大长度
@IsOptional({ always: true })
summary?: string;
}
除了官方的api我们也可以自定义验证,官网写的很清楚了,我就不写了
接下来,管道验证的用法有两种,推荐一种是全局注册
在main.js插入app.useGlobalPipes(new ValidationPipe());
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
async function bootstrap() {
// 使用fastify驱动
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter(), {
// 启用跨域访问
cors: true,
// 只使用error和warn这两种输出,避免在控制台冗余输出
logger: ['error', 'warn'],
});
app.useGlobalPipes(new ValidationPipe());
// 设置全局访问前缀
app.setGlobalPrefix('api');
// 启动后的输出
await app.listen(3000, () => {
console.log('api: http://localhost:3100');
});
}
bootstrap();
引入并且使用Dto
发个请求
第二种直接在posts.controller.ts中使用
发个请求
很明显,全局的自动帮我们格式化了报文
Decorator | Description |
Common validation decorators | |
| Checks if value is defined (!== undefined, !== null). This is the only decorator that ignores skipMissingProperties option. |
| Checks if given value is empty (=== null, === undefined) and if so, ignores all the validators on the property. |
| Checks if value equals ("===") comparison. |
| Checks if value not equal ("!==") comparison. |
| Checks if given value is empty (=== '', === null, === undefined). |
| Checks if given value is not empty (!== '', !== null, !== undefined). |
| Checks if value is in an array of allowed values. |
| Checks if value is not in an array of disallowed values. |
Type validation decorators | |
| Checks if a value is a boolean. |
| Checks if the value is a date. |
| Checks if the value is a string. |
| Checks if the value is a number. |
| Checks if the value is an integer number. |
| Checks if the value is an array |
| Checks if the value is a valid enum |
Number validation decorators | |
| Checks if the value is a number that's divisible by another. |
| Checks if the value is a positive number greater than zero. |
| Checks if the value is a negative number smaller than zero. |
| Checks if the given number is greater than or equal to given number. |
| Checks if the given number is less than or equal to given number. |
Date validation decorators | |
`@MinDate(date: Date | (() => Date))` |
`@MaxDate(date: Date | (() => Date))` |
String-type validation decorators | |
| Checks if a string is a boolean (e.g. is "true" or "false" or "1", "0"). |
| Alias for |
| Checks if a string is a number. |
String validation decorators | |
| Checks if the string contains the seed. |
| Checks if the string not contains the seed. |
| Checks if the string contains only letters (a-zA-Z). |
| Checks if the string contains only letters and numbers. |
| Checks if the string is a valid decimal value. Default IsDecimalOptions are |
| Checks if the string contains ASCII chars only. |
| Checks if a string is base32 encoded. |
| Checks if a string is base58 encoded. |
| Checks if a string is base64 encoded. |
| Checks if a string is a IBAN (International Bank Account Number). |
| Checks if a string is a BIC (Bank Identification Code) or SWIFT code. |
| Checks if the string's length (in bytes) falls in a range. |
| Checks if the string is a credit card. |
| Checks if the string is a valid currency amount. |
| Checks if the string is an ISO 4217 currency code. |
| Checks if the string is an Ethereum address using basic regex. Does not validate address checksums. |
| Checks if the string is a valid BTC address. |
| Checks if the string is a data uri format. |
| Checks if the string is an email. |
| Checks if the string is a fully qualified domain name (e.g. domain.com). |
| Checks if the string contains any full-width chars. |
| Checks if the string contains any half-width chars. |
| Checks if the string contains a mixture of full and half-width chars. |
| Checks if the string is a hexadecimal color. |
| Checks if the string is an HSL color based on CSS Colors Level 4 specification. |
| Checks if the string is a rgb or rgba color. |
| Checks if the string is a valid identity card code. |
| Checks if the string is a valid passport number relative to a specific country code. |
| Checks if the string is a postal code. |
| Checks if the string is a hexadecimal number. |
| Checks if the string is a octal number. |
| Checks if the string is a MAC Address. |
| Checks if the string is an IP (version 4 or 6). |
| Checks if the string is a valid port number. |
| Checks if the string is an ISBN (version 10 or 13). |
| Checks if the string is an if the string is an EAN (European Article Number). |
| Checks if the string is an ISIN (stock/security identifier). |
| Checks if the string is a valid ISO 8601 date format. Use the option strict = true for additional checks for a valid date. |
| Checks if the string is valid JSON. |
| Checks if the string is valid JWT. |
| Checks if the object is valid Object (null, functions, arrays will return false). |
| Checks if the object is not empty. |
| Checks if the string is lowercase. |
| Checks if the string is a valid latitude-longitude coordinate in the format lat, long. |
| Checks if the string or number is a valid latitude coordinate. |
| Checks if the string or number is a valid longitude coordinate. |
| Checks if the string is a mobile phone number. |
| Checks if the string is a valid ISO 3166-1 alpha-2 officially assigned country code. |
| Checks if the string is a valid ISO 3166-1 alpha-3 officially assigned country code. |
| Checks if the string is a locale. |
| Checks if the string is a valid phone number using libphonenumber-js. |
| Checks if the string is a valid hex-encoded representation of a MongoDB ObjectId. |
| Checks if the string contains one or more multibyte chars. |
| Checks if the string is numeric. |
| Checks if the string contains any surrogate pairs chars. |
| Checks if the string is a valid tax ID. Default locale is |
| Checks if the string is a URL. |
| Checks if the string is a magnet uri format. |
| Checks if the string is a UUID (version 3, 4, 5 or all ). |
| Checks if the string is a Firebase Push ID |
| Checks if the string is uppercase. |
| Checks if the string's length falls in a range. |
| Checks if the string's length is not less than given number. |
| Checks if the string's length is not more than given number. |
| Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i'). |
| Checks if the string is a valid representation of military time in the format HH:MM. |
| Checks if the string represents a valid IANA time-zone. |
| Checks if the string is a hash The following types are supported: |
| Checks if the string matches to a valid MIME type format |
| Checks if the string is a Semantic Versioning Specification (SemVer). |
| Checks if the string is a ISSN. |
| Checks if the string is a ISRC. |
| Checks if the string is a valid RFC 3339 date. |
| Checks if the string is a strong password. |
Array validation decorators | |
| Checks if array contains all values from the given array of values. |
| Checks if array does not contain any of the given values. |
| Checks if given array is not empty. |
| Checks if the array's length is greater than or equal to the specified number. |
| Checks if the array's length is less or equal to the specified number. |
| Checks if all array's values are unique. Comparison for objects is reference-based. Optional function can be speciefied which return value will be used for the comparsion. |
Object validation decorators | |
| Checks if the property is an instance of the passed value. |
Other decorators | |
| Prevent stripping off the property when no other constraint is specified for it. |