学习nest.js的第三天

昨天学到接口,有接口就有验证,所以今天学管道和验证

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中使用

发个请求

很明显,全局的自动帮我们格式化了报文

DecoratorDescription
Common validation decorators
@IsDefined(value: any)Checks if value is defined (!== undefined, !== null). This is the only decorator that ignores skipMissingProperties option.
@IsOptional()Checks if given value is empty (=== null, === undefined) and if so, ignores all the validators on the property.
@Equals(comparison: any)Checks if value equals ("===") comparison.
@NotEquals(comparison: any)Checks if value not equal ("!==") comparison.
@IsEmpty()Checks if given value is empty (=== '', === null, === undefined).
@IsNotEmpty()Checks if given value is not empty (!== '', !== null, !== undefined).
@IsIn(values: any[])Checks if value is in an array of allowed values.
@IsNotIn(values: any[])Checks if value is not in an array of disallowed values.
Type validation decorators
@IsBoolean()Checks if a value is a boolean.
@IsDate()Checks if the value is a date.
@IsString()Checks if the value is a string.
@IsNumber(options: IsNumberOptions)Checks if the value is a number.
@IsInt()Checks if the value is an integer number.
@IsArray()Checks if the value is an array
@IsEnum(entity: object)Checks if the value is a valid enum
Number validation decorators
@IsDivisibleBy(num: number)Checks if the value is a number that's divisible by another.
@IsPositive()Checks if the value is a positive number greater than zero.
@IsNegative()Checks if the value is a negative number smaller than zero.
@Min(min: number)Checks if the given number is greater than or equal to given number.
@Max(max: 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
@IsBooleanString()Checks if a string is a boolean (e.g. is "true" or "false" or "1", "0").
@IsDateString()Alias for @IsISO8601().
@IsNumberString(options?: IsNumericOptions)Checks if a string is a number.
String validation decorators
@Contains(seed: string)Checks if the string contains the seed.
@NotContains(seed: string)Checks if the string not contains the seed.
@IsAlpha()Checks if the string contains only letters (a-zA-Z).
@IsAlphanumeric()Checks if the string contains only letters and numbers.
@IsDecimal(options?: IsDecimalOptions)Checks if the string is a valid decimal value. Default IsDecimalOptions are force_decimal=False, decimal_digits: '1,', locale: 'en-US'
@IsAscii()Checks if the string contains ASCII chars only.
@IsBase32()Checks if a string is base32 encoded.
@IsBase58()Checks if a string is base58 encoded.
@IsBase64()Checks if a string is base64 encoded.
@IsIBAN()Checks if a string is a IBAN (International Bank Account Number).
@IsBIC()Checks if a string is a BIC (Bank Identification Code) or SWIFT code.
@IsByteLength(min: number, max?: number)Checks if the string's length (in bytes) falls in a range.
@IsCreditCard()Checks if the string is a credit card.
@IsCurrency(options?: IsCurrencyOptions)Checks if the string is a valid currency amount.
@IsISO4217CurrencyCode()Checks if the string is an ISO 4217 currency code.
@IsEthereumAddress()Checks if the string is an Ethereum address using basic regex. Does not validate address checksums.
@IsBtcAddress()Checks if the string is a valid BTC address.
@IsDataURI()Checks if the string is a data uri format.
@IsEmail(options?: IsEmailOptions)Checks if the string is an email.
@IsFQDN(options?: IsFQDNOptions)Checks if the string is a fully qualified domain name (e.g. domain.com).
@IsFullWidth()Checks if the string contains any full-width chars.
@IsHalfWidth()Checks if the string contains any half-width chars.
@IsVariableWidth()Checks if the string contains a mixture of full and half-width chars.
@IsHexColor()Checks if the string is a hexadecimal color.
@IsHSL()Checks if the string is an HSL color based on CSS Colors Level 4 specification.
@IsRgbColor(options?: IsRgbOptions)Checks if the string is a rgb or rgba color.
@IsIdentityCard(locale?: string)Checks if the string is a valid identity card code.
@IsPassportNumber(countryCode?: string)Checks if the string is a valid passport number relative to a specific country code.
@IsPostalCode(locale?: string)Checks if the string is a postal code.
@IsHexadecimal()Checks if the string is a hexadecimal number.
@IsOctal()Checks if the string is a octal number.
@IsMACAddress(options?: IsMACAddressOptions)Checks if the string is a MAC Address.
@IsIP(version?: "4"|"6")Checks if the string is an IP (version 4 or 6).
@IsPort()Checks if the string is a valid port number.
@IsISBN(version?: "10"|"13")Checks if the string is an ISBN (version 10 or 13).
@IsEAN()Checks if the string is an if the string is an EAN (European Article Number).
@IsISIN()Checks if the string is an ISIN (stock/security identifier).
@IsISO8601(options?: IsISO8601Options)Checks if the string is a valid ISO 8601 date format. Use the option strict = true for additional checks for a valid date.
@IsJSON()Checks if the string is valid JSON.
@IsJWT()Checks if the string is valid JWT.
@IsObject()Checks if the object is valid Object (null, functions, arrays will return false).
@IsNotEmptyObject()Checks if the object is not empty.
@IsLowercase()Checks if the string is lowercase.
@IsLatLong()Checks if the string is a valid latitude-longitude coordinate in the format lat, long.
@IsLatitude()Checks if the string or number is a valid latitude coordinate.
@IsLongitude()Checks if the string or number is a valid longitude coordinate.
@IsMobilePhone(locale: string)Checks if the string is a mobile phone number.
@IsISO31661Alpha2()Checks if the string is a valid ISO 3166-1 alpha-2 officially assigned country code.
@IsISO31661Alpha3()Checks if the string is a valid ISO 3166-1 alpha-3 officially assigned country code.
@IsLocale()Checks if the string is a locale.
@IsPhoneNumber(region: string)Checks if the string is a valid phone number using libphonenumber-js.
@IsMongoId()Checks if the string is a valid hex-encoded representation of a MongoDB ObjectId.
@IsMultibyte()Checks if the string contains one or more multibyte chars.
@IsNumberString(options?: IsNumericOptions)Checks if the string is numeric.
@IsSurrogatePair()Checks if the string contains any surrogate pairs chars.
@IsTaxId()Checks if the string is a valid tax ID. Default locale is en-US.
@IsUrl(options?: IsURLOptions)Checks if the string is a URL.
@IsMagnetURI()Checks if the string is a magnet uri format.
@IsUUID(version?: "3"|"4"|"5"|"all")Checks if the string is a UUID (version 3, 4, 5 or all ).
@IsFirebasePushId()Checks if the string is a Firebase Push ID
@IsUppercase()Checks if the string is uppercase.
@Length(min: number, max?: number)Checks if the string's length falls in a range.
@MinLength(min: number)Checks if the string's length is not less than given number.
@MaxLength(max: number)Checks if the string's length is not more than given number.
@Matches(pattern: RegExp, modifiers?: string)Checks if string matches the pattern. Either matches('foo', /foo/i) or matches('foo', 'foo', 'i').
@IsMilitaryTime()Checks if the string is a valid representation of military time in the format HH:MM.
@IsTimeZone()Checks if the string represents a valid IANA time-zone.
@IsHash(algorithm: string)Checks if the string is a hash The following types are supported:md4, md5, sha1, sha256, sha384, sha512, ripemd128, ripemd160, tiger128, tiger160, tiger192, crc32, crc32b.
@IsMimeType()Checks if the string matches to a valid MIME type format
@IsSemVer()Checks if the string is a Semantic Versioning Specification (SemVer).
@IsISSN(options?: IsISSNOptions)Checks if the string is a ISSN.
@IsISRC()Checks if the string is a ISRC.
@IsRFC3339()Checks if the string is a valid RFC 3339 date.
@IsStrongPassword(options?: IsStrongPasswordOptions)Checks if the string is a strong password.
Array validation decorators
@ArrayContains(values: any[])Checks if array contains all values from the given array of values.
@ArrayNotContains(values: any[])Checks if array does not contain any of the given values.
@ArrayNotEmpty()Checks if given array is not empty.
@ArrayMinSize(min: number)Checks if the array's length is greater than or equal to the specified number.
@ArrayMaxSize(max: number)Checks if the array's length is less or equal to the specified number.
@ArrayUnique(identifier?: (o) => any)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
@IsInstance(value: any,validationOptions?: ValidationOptions)Checks if the property is an instance of the passed value.
Other decorators
@Allow()Prevent stripping off the property when no other constraint is specified for it.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值