Home >Web Front-end >JS Tutorial >zod vs class-validator & class-transformer

zod vs class-validator & class-transformer

Patricia Arquette
Patricia ArquetteOriginal
2024-12-19 11:42:18766browse

zod vs class-validator & class-transformer

Comparison of zod with class-validator & class-transformer in NestJS

I was confused, or at least curious between zod or class-validator & class-transformer
as a validation library in NestJS.

Main Point

Just go straight to it.

1. Reasons for choosing class-validator & class-transformer

  • Is a duo packages that are common & widely used in NestJS
  • The writing method is very NestJS because it is decorator-based validation
  • clean & seamless integration with its use with class-transformer & ValidationPipe

2. Reasons for choosing Zod

  • Framework agnostic
  • Very typescript
  • For those who prefer functional & schema-based approach
  • Performance & lightweight validation is critical

Details

class-validator & class-transformer are the 2 packages most commonly used as validation in NestJS,
yes, apart from the fact that the writing method is the same as NestJS using decorator-based,
also because it is clean & seamless because it can be used with ValidationPipe as DTO.

So the incoming data/payload received by the controller has been validated & changed/transformed according to its definition.
Meanwhile, Zod still needs to manually validate the data/payload received,
Yes, maybe only 1 or a maximum of 3 lines,
but of course the more validation functions are needed, the more manual processes are needed.

Procedure details

The following are detailed procedures (may be subjective) for comparison.

class-validator & class-transformer

1. Installation

npm install class-validator class-transformer

2. Enable Global Validation

// main.ts
....
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
....
  // Enable validation globally
  app.useGlobalPipes(new ValidationPipe({
    transform: true, // Automatically transform payloads to DTO instances
    whitelist: true, // Strip unknown properties
    forbidNonWhitelisted: true, // Throw error for unknown properties
  }));
....
}
....

3. Define DTO (Data Transfer Object)

import { IsNotEmpty, IsString, IsInt, Min } from "class-validator";
import { Type, Transform } from "class-transformer";

export class CreateUserDto {
    @Transform(({ value }) => value.trim()) // Trim whitespaces
    @IsNotEmpty({ message: "Nama tidak boleh kosong" })
    @IsString({ message: "Nama harus berupa string" })
    @Min(3, { message: "Minimal panjang nama 3 karakter" })
    name: string;

    @Type(() => Number) // Transform input ke tipe Number
    @IsNotEmpty({ message: "Nama tidak boleh kosong" })
    @IsInt({ message: "Umur harus berupa bilangan bulat" })
    @Min(17, { message: "Minimal umur terdaftar 17 tahun" })
    age: number;
}

It's quite long, but that's how it is decorator-based.

4. Use of validation

import { Body, Controller, Post } from "@nestjs/common";
import { CreateUserDto } from "./create-user.dto";

@Controller("users")
export class UsersController {
    @Post()
    create(@Body() createUserDto: CreateUserDto) {
        // Pada titik ini data/payload createUserdDto
        // sudah tervalidasi & diubah sesuai definisinya
        // developer bisa langsung eksekusi service
        // atau logic yang lain
    }
}

Zod

1. Installation

npm install zod

2. Create Validation Scheme

// user.validaiton.ts
import { z, ZodType } from "zod";

export class UserValidation {
    static readonly CREATE: ZodType = z.object({
        name: z
            .string({ message: "Nama harus berupa string" })
            .nonempty({ message: "Nama tidak boleh kosong" })
            .min(3, "Minimal panjang nama 13 karakter"),
        age: z
            .number({ message: "Umur harus berupa angka" })
            .int({ message: "Umur harus berupa bilangan bulat" })
            .min(17, "Minimal umur terdaftar 17 tahub"),
    });
}

export type TCreateUserPayload = z.infer<typeof UserValidation.CREATE>;

*Personal: I prefer reading this schema than the one above

3. Use of validation

import { Body, Controller, Post } from "@nestjs/common";
import { UserValidation, TCreateUserPayload } from "./user.validation.ts";

@Controller("users")
export class UsersController {
    @Post()
    create(@Body() createUserPayload: TCreateUserPayload) {
        const payload = UserValidation.CREATE.parse(createUserPayload);
        // Pada titik ini data/payload payload
        // sudah tervalidasi & diubah sesuai definisinya
        // developer bisa langsung eksekusi service
        // atau logic yang lain
    }
}

Conclusion

Personally I prefer the way Zod is used.
However, what needs to be underlined is choose according to the team's needs & standards.

https://abdulghofurme.github.io/posts/zod-vs-class-validator-n-class-transformer/

The above is the detailed content of zod vs class-validator & class-transformer. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn