Monday

18-08-2025 Vol 19

Nest JS Class Validator & Class Transformers

Validasi dan Transformasi Data Tingkat Lanjut dengan NestJS Class Validator dan Class Transformer

NestJS, framework progresif untuk membangun aplikasi Node.js yang efisien dan terukur, menawarkan banyak sekali alat dan pustaka untuk mempermudah pengembangan. Di antara alat-alat ini, Class Validator dan Class Transformer menonjol sebagai pustaka yang sangat berharga untuk menangani validasi dan transformasi data. Keduanya memungkinkan Anda menerapkan validasi dan transformasi data yang kuat dan deklaratif menggunakan dekorator, yang mengarah pada kode yang lebih bersih, mudah dipelihara, dan mudah dibaca. Artikel ini akan membahas secara mendalam tentang pustaka-pustaka ini, menjelaskan bagaimana cara menggunakannya secara efektif di aplikasi NestJS Anda, dan memberikan wawasan tentang praktik terbaik.

Mengapa Validasi dan Transformasi Data Penting?

Sebelum menyelami detail implementasi, mari kita pahami mengapa validasi dan transformasi data sangat penting dalam pengembangan aplikasi:

  1. Integritas Data: Validasi memastikan bahwa data yang diterima oleh aplikasi Anda memenuhi kriteria tertentu. Ini mencegah data yang tidak valid atau korup memasuki sistem Anda, yang dapat menyebabkan kesalahan, perilaku tak terduga, dan bahkan kerentanan keamanan.
  2. Keamanan: Memvalidasi input pengguna adalah langkah penting dalam mencegah serangan seperti injeksi SQL dan skrip lintas situs (XSS). Dengan memvalidasi input, Anda dapat memastikan bahwa hanya data yang aman dan diharapkan yang diproses oleh aplikasi Anda.
  3. Pengalaman Pengguna: Validasi yang tepat memberikan umpan balik yang jelas kepada pengguna tentang kesalahan dalam input mereka, memungkinkan mereka untuk memperbaikinya dengan cepat. Ini meningkatkan pengalaman pengguna dan mengurangi frustrasi.
  4. Kode yang Dapat Dipelihara: Dengan mendefinisikan aturan validasi dan transformasi secara deklaratif menggunakan dekorator, Anda membuat kode Anda lebih mudah dibaca, dipahami, dan dipelihara. Aturan-aturan ini terpusat dan mudah dimodifikasi tanpa memengaruhi logika bisnis yang mendasarinya.

Memperkenalkan Class Validator

Class Validator adalah pustaka validasi berbasis deklaratif yang menggunakan dekorator untuk mendefinisikan aturan validasi pada properti kelas. Ia bekerja dengan baik dengan NestJS dan menyediakan cara yang ramping dan efisien untuk memvalidasi data yang masuk.

Instalasi

Untuk menggunakan Class Validator di proyek NestJS Anda, Anda perlu menginstalnya menggunakan npm atau yarn:


    npm install class-validator class-transformer --save
  

Atau:


    yarn add class-validator class-transformer
  

Perhatikan bahwa kita juga menginstal class-transformer. Ini karena Class Validator sering bekerja sama dengan Class Transformer untuk melakukan transformasi data selama proses validasi.

Konfigurasi di NestJS

Setelah Anda menginstal pustaka, Anda perlu mengaktifkan validasi di aplikasi NestJS Anda. Anda dapat melakukan ini dengan menggunakan ValidationPipe global. Buka file main.ts Anda dan tambahkan yang berikut:


    // main.ts
    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    import { ValidationPipe } from '@nestjs/common';

    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      app.useGlobalPipes(new ValidationPipe());
      await app.listen(3000);
    }
    bootstrap();
  

ValidationPipe secara otomatis akan memvalidasi data yang masuk berdasarkan aturan yang ditentukan dalam kelas Anda.

Mendefinisikan Kelas Validasi

Untuk menggunakan Class Validator, Anda perlu membuat kelas yang mewakili struktur data yang ingin Anda validasi dan menambahkan dekorator ke properti kelas untuk menentukan aturan validasi.

Berikut adalah contoh:


    // create-user.dto.ts
    import { IsString, IsEmail, IsNotEmpty, MinLength, MaxLength } from 'class-validator';

    export class CreateUserDto {
      @IsString()
      @IsNotEmpty()
      @MinLength(3)
      @MaxLength(20)
      firstName: string;

      @IsString()
      @IsNotEmpty()
      @MinLength(3)
      @MaxLength(20)
      lastName: string;

      @IsEmail()
      @IsNotEmpty()
      email: string;
    }
  

Dalam contoh ini, kita mendefinisikan kelas CreateUserDto dengan tiga properti: firstName, lastName, dan email. Kita menggunakan dekorator dari class-validator untuk menentukan aturan validasi untuk setiap properti:

  • @IsString(): Memastikan properti tersebut adalah string.
  • @IsNotEmpty(): Memastikan properti tersebut tidak kosong.
  • @MinLength(3): Memastikan string setidaknya sepanjang 3 karakter.
  • @MaxLength(20): Memastikan string tidak lebih panjang dari 20 karakter.
  • @IsEmail(): Memastikan string tersebut adalah email yang valid.

Menggunakan Kelas Validasi di Controller

Setelah Anda mendefinisikan kelas validasi, Anda dapat menggunakannya di controller NestJS Anda untuk memvalidasi data yang masuk.


    // users.controller.ts
    import { Controller, Post, Body, ValidationPipe } from '@nestjs/common';
    import { CreateUserDto } from './dto/create-user.dto';

    @Controller('users')
    export class UsersController {
      @Post()
      async createUser(@Body(new ValidationPipe()) createUserDto: CreateUserDto) {
        // Lakukan sesuatu dengan data pengguna yang divalidasi
        console.log(createUserDto);
        return { message: 'Pengguna berhasil dibuat' };
      }
    }
  

Dalam contoh ini, kita menggunakan decorator @Body() untuk mendapatkan data dari body permintaan. Kita juga meneruskan instance dari ValidationPipe ke decorator @Body(). Ini akan secara otomatis memvalidasi data yang masuk terhadap aturan yang ditentukan dalam kelas CreateUserDto.

Jika data tidak valid, ValidationPipe akan melempar pengecualian BadRequestException dengan daftar kesalahan validasi. NestJS akan secara otomatis menangkap pengecualian ini dan mengembalikan respons kesalahan ke klien.

Pustaka Class Transformer

Class Transformer adalah pustaka yang digunakan untuk mentransformasi objek dari satu bentuk ke bentuk lainnya. Ini sering digunakan bersama dengan Class Validator untuk membersihkan dan mentransformasi data setelah validasi.

Instalasi

Class Transformer diinstal bersamaan dengan Class Validator. Jika Anda belum menginstalnya, ikuti instruksi instalasi di bagian Class Validator.

Menggunakan Class Transformer

Class Transformer menggunakan dekorator untuk mendefinisikan bagaimana properti harus ditransformasi. Contoh umum termasuk mengonversi string menjadi angka, memangkas spasi, atau mengubah nama properti.

Berikut adalah contoh:


    // update-user.dto.ts
    import { IsString, IsOptional, IsNumber, ToNumber } from 'class-validator';
    import { Transform } from 'class-transformer';

    export class UpdateUserDto {
      @IsString()
      @IsOptional()
      firstName?: string;

      @IsString()
      @IsOptional()
      lastName?: string;

      @IsNumber()
      @IsOptional()
      @ToNumber() // Transformasi ke angka
      age?: number;

      @IsString()
      @IsOptional()
      @Transform(({ value }) => value.trim()) // Memangkas spasi
      description?: string;
    }

    function ToNumber() {
      return Transform(({ value }) => {
        try {
          const parsedValue = Number(value);
          return isNaN(parsedValue) ? value : parsedValue;
        } catch (e) {
          return value;
        }
      });
    }
  

Dalam contoh ini:

  • @ToNumber(): Fungsi custom yang menggunakan decorator @Transform untuk mencoba mengonversi nilai age ke sebuah angka. Jika konversi berhasil, angka dikembalikan. Jika tidak, nilai aslinya dikembalikan.
  • @Transform(({ value }) => value.trim()): Decorator @Transform digunakan untuk memangkas (menghapus spasi di awal dan akhir) nilai properti description.

Menggunakan Class Transformer di Controller

Untuk menggunakan Class Transformer, Anda perlu menyertakan opsi transform: true dalam ValidationPipe Anda.


    // users.controller.ts
    import { Controller, Put, Body, Param, ValidationPipe } from '@nestjs/common';
    import { UpdateUserDto } from './dto/update-user.dto';

    @Controller('users')
    export class UsersController {
      @Put(':id')
      async updateUser(
        @Param('id') id: string,
        @Body(new ValidationPipe({ transform: true })) updateUserDto: UpdateUserDto,
      ) {
        // Lakukan sesuatu dengan data pengguna yang divalidasi dan ditransformasi
        console.log(updateUserDto);
        return { message: 'Pengguna berhasil diperbarui' };
      }
    }
  

Dengan menambahkan transform: true ke ValidationPipe, Class Transformer secara otomatis akan menerapkan transformasi yang ditentukan pada data sebelum validasi.

Contoh Lebih Lanjut dan Dekorator Umum

Class Validator menyediakan berbagai macam dekorator yang telah ditentukan sebelumnya yang dapat Anda gunakan untuk memvalidasi data. Berikut adalah beberapa contoh umum:

  • @IsDefined(): Memastikan properti tersebut terdefinisi.
  • @IsBoolean(): Memastikan properti tersebut adalah boolean.
  • @IsDate(): Memastikan properti tersebut adalah tanggal yang valid.
  • @IsIn(['value1', 'value2']): Memastikan properti tersebut adalah salah satu dari nilai yang ditentukan.
  • @IsOptional(): Menunjukkan properti tersebut opsional dan dapat dihilangkan. Jika ada, ia akan divalidasi.
  • @ValidateNested(): Digunakan untuk memvalidasi properti yang merupakan objek lain. Anda harus menambahkan { each: true } jika properti tersebut adalah array objek.

Anda juga dapat membuat dekorator validasi khusus Anda sendiri jika Anda memerlukan logika validasi yang lebih kompleks.

Validasi Bersarang

Saat memvalidasi objek yang mengandung objek lain, Anda perlu menggunakan decorator @ValidateNested(). Berikut adalah contoh:


    // address.dto.ts
    import { IsString, IsNotEmpty } from 'class-validator';

    export class AddressDto {
      @IsString()
      @IsNotEmpty()
      street: string;

      @IsString()
      @IsNotEmpty()
      city: string;
    }

    // create-user.dto.ts
    import { IsString, IsEmail, IsNotEmpty, ValidateNested } from 'class-validator';
    import { Type } from 'class-transformer';
    import { AddressDto } from './address.dto';

    export class CreateUserDto {
      @IsString()
      @IsNotEmpty()
      firstName: string;

      @IsString()
      @IsNotEmpty()
      lastName: string;

      @IsEmail()
      @IsNotEmpty()
      email: string;

      @ValidateNested()
      @Type(() => AddressDto)
      address: AddressDto;
    }
  

Dalam contoh ini, kelas CreateUserDto memiliki properti address yang merupakan instance dari kelas AddressDto. Kita menggunakan decorator @ValidateNested() untuk menunjukkan bahwa properti address harus divalidasi menggunakan aturan yang ditentukan dalam kelas AddressDto. Decorator @Type(() => AddressDto) dari class-transformer diperlukan untuk menginstruksikan Class Transformer cara membuat instance dari AddressDto. Tanpanya, validasi pada AddressDto tidak akan berfungsi.

Array Validasi

Untuk memvalidasi array, Anda dapat menggunakan opsi each: true dalam decorator validasi dan juga @ValidateNested() jika array berisi objek.


    // create-user.dto.ts
    import { IsString, IsEmail, IsNotEmpty, ValidateNested, IsArray } from 'class-validator';
    import { Type } from 'class-transformer';
    import { AddressDto } from './address.dto';

    export class CreateUserDto {
      @IsString()
      @IsNotEmpty()
      firstName: string;

      @IsString()
      @IsNotEmpty()
      lastName: string;

      @IsEmail()
      @IsNotEmpty()
      email: string;

      @IsArray()
      @ValidateNested({ each: true })
      @Type(() => AddressDto)
      addresses: AddressDto[];
    }
  

Dalam contoh ini, properti addresses adalah array dari instance AddressDto. Decorator @ValidateNested({ each: true }) memastikan setiap elemen dalam array addresses divalidasi menggunakan aturan dalam AddressDto.

Praktik Terbaik untuk Validasi dan Transformasi Data

Berikut adalah beberapa praktik terbaik untuk validasi dan transformasi data di aplikasi NestJS:

  1. Gunakan Class Validator dan Class Transformer: Pustaka-pustaka ini menyediakan cara yang deklaratif dan efisien untuk memvalidasi dan mentransformasi data, yang mengarah pada kode yang lebih bersih dan mudah dipelihara.
  2. Validasi di Lapisan Controller: Lakukan validasi data yang masuk di lapisan controller untuk memastikan bahwa hanya data yang valid yang diproses oleh aplikasi Anda.
  3. Tentukan Aturan Validasi yang Jelas dan Ringkas: Buat aturan validasi yang jelas dan ringkas untuk setiap properti data Anda. Ini akan membuatnya lebih mudah untuk memahami dan memelihara aturan validasi Anda.
  4. Berikan Umpan Balik Kesalahan yang Bermakna: Berikan umpan balik kesalahan yang bermakna kepada pengguna saat data mereka tidak valid. Ini akan membantu mereka untuk memperbaiki kesalahan mereka dan meningkatkan pengalaman pengguna. Anda dapat menyesuaikan pesan kesalahan bawaan menggunakan opsi message di setiap decorator.
  5. Gunakan Validasi Bersarang untuk Objek Kompleks: Gunakan validasi bersarang untuk memvalidasi objek kompleks yang mengandung objek lain. Ini akan memastikan bahwa semua data dalam objek divalidasi dengan benar.
  6. Pertimbangkan Kinerja: Meskipun Class Validator dan Class Transformer sangat efisien, ingatlah untuk mempertimbangkan kinerja saat menerapkan validasi dan transformasi yang kompleks. Hindari validasi yang berlebihan dan optimalkan kode transformasi Anda untuk performa yang optimal.

Menangani Pesan Kesalahan Khusus

Anda dapat menyesuaikan pesan kesalahan yang dikembalikan oleh Class Validator dengan memberikan opsi message ke decorator:


    // create-user.dto.ts
    import { IsString, IsEmail, IsNotEmpty, MinLength, MaxLength } from 'class-validator';

    export class CreateUserDto {
      @IsString({ message: 'Nama depan harus berupa string' })
      @IsNotEmpty({ message: 'Nama depan tidak boleh kosong' })
      @MinLength(3, { message: 'Nama depan harus minimal 3 karakter' })
      @MaxLength(20, { message: 'Nama depan tidak boleh lebih dari 20 karakter' })
      firstName: string;

      @IsString({ message: 'Nama belakang harus berupa string' })
      @IsNotEmpty({ message: 'Nama belakang tidak boleh kosong' })
      @MinLength(3, { message: 'Nama belakang harus minimal 3 karakter' })
      @MaxLength(20, { message: 'Nama belakang tidak boleh lebih dari 20 karakter' })
      lastName: string;

      @IsEmail({}, { message: 'Email harus berupa email yang valid' })
      @IsNotEmpty({ message: 'Email tidak boleh kosong' })
      email: string;
    }
  

Sekarang, jika validasi gagal, pesan kesalahan yang disesuaikan akan dikembalikan alih-alih pesan default.

Membuat Validator Kustom

Terkadang, Anda akan memerlukan logika validasi yang lebih kompleks yang tidak tercakup oleh validator yang telah ditentukan sebelumnya. Dalam kasus ini, Anda dapat membuat validator kustom.

  1. Buat Kelas Validator Kustom: Buat kelas yang mengimplementasikan antarmuka ValidatorConstraintInterface dari class-validator.
  2. Implementasikan Metode validate dan defaultMessage: Implementasikan metode validate, yang berisi logika validasi Anda, dan metode defaultMessage, yang mengembalikan pesan kesalahan default jika validasi gagal.
  3. Gunakan Decorator @ValidatorConstraint: Hiasi kelas validator Anda dengan decorator @ValidatorConstraint.
  4. Gunakan Validator Kustom di DTO Anda: Gunakan decorator @Validate untuk menggunakan validator kustom Anda di DTO Anda.

Berikut adalah contoh validator kustom yang memeriksa apakah string berisi kata tertentu:


    // contains-word.validator.ts
    import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';

    @ValidatorConstraint({ name: 'containsWord', async: false })
    export class ContainsWordConstraint implements ValidatorConstraintInterface {
      validate(text: string, args: ValidationArguments) {
        const word = args.constraints[0];
        return typeof text === 'string' && text.includes(word);
      }

      defaultMessage(args: ValidationArguments) {
        const word = args.constraints[0];
        return `Teks harus mengandung kata: ${word}`;
      }
    }

    // create-user.dto.ts
    import { IsString, IsNotEmpty, Validate } from 'class-validator';
    import { ContainsWordConstraint } from './contains-word.validator';

    export class CreateUserDto {
      @IsString()
      @IsNotEmpty()
      firstName: string;

      @IsString()
      @IsNotEmpty()
      lastName: string;

      @Validate(ContainsWordConstraint, ['foo'])
      description: string;
    }
  

Dalam contoh ini, ContainsWordConstraint memvalidasi apakah properti description mengandung kata “foo”.

Kesimpulan

Class Validator dan Class Transformer adalah pustaka yang sangat kuat yang menyederhanakan validasi dan transformasi data di aplikasi NestJS. Dengan menggunakan dekorator, Anda dapat mendefinisikan aturan validasi dan transformasi secara deklaratif, yang mengarah pada kode yang lebih bersih, mudah dipelihara, dan aman. Dengan mengikuti praktik terbaik yang dijelaskan dalam artikel ini, Anda dapat memastikan bahwa aplikasi NestJS Anda menangani data dengan benar dan aman, yang meningkatkan pengalaman pengguna dan mengurangi risiko kesalahan.

Dengan menguasai pustaka-pustaka ini, Anda dapat meningkatkan kualitas dan ketahanan aplikasi NestJS Anda secara signifikan.

“`

omcoding

Leave a Reply

Your email address will not be published. Required fields are marked *