[NestJS] DTO validation

The problem
Ví dụ chúng ta có một DTO dưới đây, nếu mà chúng ta ko manual kiểm tra hoặc convert kiểu của các fields này thì payload hoàn toàn có thể có bất kỳ dạng data nào:
export class CreateUserDto {
username: string;
email: string;
password: string;
isAdmin: boolean;
age: number;
}
The solution
DTO validation là việc chúng ta kiểm soát kiểu của dữ liệu đầu vào của API để đảm bảo rằng chúng đúng với format mà chúng ta quy định ở các parameter khác trong handler của chúng ta. Tránh trường hợp xử lý với một dữ liệu không đúng kiểu.
Sử dụng Validator trong NestJS sẽ giúp chúng ta:
Đảm bảo dữ liệu đầu vào đúng kiểu dữ liệu
Đúng điều kiện / constrain cần thiết (độ dài…)
Không cần muanual convert kiểu hoặc handle exception.
- installation
npm install class-validator class-transformer
- Use validation decorator for DTO class
Sử dụng các decorator được cung cấp sẵn theo nhu cầu của mình.
import {
IsString,
IsEmail,
IsNotEmpty,
MinLength,
IsBoolean,
} from 'class-validator';
export class CreateUserDto {
@IsString()
@IsNotEmpty()
username: string;
@IsEmail()
@IsNotEmpty()
email: string;
@IsString()
@MinLength(6)
@IsNotEmpty()
password: string;
@IsBoolean()
@IsNotEmpty()
isAdmin: boolean;
}
- Enable validation pipe at application level
Để các validation của ta có tác dụng, ta cần phải enable ValidationPipe
ở application level lên trong main.ts
file.
app.useGlobalPipes(new ValidationPipe());
Extend
Một số kỹ thuật mở rộng khác.
Auto transform primitive type
Desc: Khi sử dụng GET method, các param mặc định sẽ thuộc kiểu string, điều này sẽ gây bất lợi nếu chúng ta cần param thuộc kiểu khác.
Exp: Ta có enpoint sau: GET http://localhost:3000/users/age/10
Và ở dưới ta có logic sau: age === 10
Logic này sẽ return false nếu age ko phải kiểu number.
How: Trong trường hợp này ta enable transform
trong Validation Pipe lên.
app.useGlobalPipes(
new ValidationPipe({
transform: true,
}),
);
- Transform in DTO
Trong trường hợp DTO nằm trong GET method, ko thể auto convert như trên dược.
Chúng ta có GET end point để search user như sau:
@Get('users')
filters(@Query() params: FilterUsersDto) {
return params;
}
DTO
import { IsNotEmpty, IsNumber, IsString } from 'class-validator';
export class FilterUsersDto {
@IsNumber()
@IsNotEmpty()
age: number;
@IsString()
@IsNotEmpty()
name: string;
}
Đã enable transform: true,
trong hàm main.
\==> NestJS ko thể tự convert trong trường hợp sử dụng DTO.
\==> Ta phải manual transform với trasformer của NestJS.
import { Transform } from 'class-transformer';
...
@Transform(({ value }) => Number(value))
Ref:
Subscribe to my newsletter
Read articles from The Brown Box directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
