C. Validation
1. Apa itu Validation?
Validation bertujuan untuk memastikan bahwa data yang dikirimkan atau diterima oleh aplikasi Anda sesuai dengan aturan atau kriteria tertentu sebelum diproses lebih lanjut. Selain itu berikut merupakan tujuan dari Validation
-
Data Integritas
: Memastikan bahwa data yang diterima sesuai dengan struktur dan tipe yang diharapkan sehingga tidak menyebabkan kesalahan atau gangguan dalam pemrosesan lebih lanjut. -
Validasi Input
: Memvalidasi data masukan dari pengguna atau dari sumber eksternal untuk memastikan bahwa data tersebut sesuai dengan aturan yang ditetapkan. Misalnya, memastikan bahwa sebuah email memiliki format yang benar, atau bahwa nomor telepon hanya berisi angka. -
Keamanan
: Menghindari masalah keamanan seperti SQL injection atau penyusupan berdasarkan data yang tidak valid. -
Meningkatkan Pesan Error
: Memberikan pesan error yang bermakna dan informatif ketika data tidak valid, sehingga memudahkan pengguna untuk memperbaikinya. -
Dokumentasi
: Dengan menggunakan class validator, Anda dapat mendokumentasikan aturan validasi secara eksplisit di level DTO, yang dapat membantu pengembang lain untuk memahami kebutuhan data dan aturan validasi yang berlaku. -
Mengurangi Kesalahan
: Dengan melakukan validasi sejak awal, Anda dapat mengidentifikasi dan menangani kesalahan lebih cepat dan lebih mudah sebelum data digunakan dalam proses bisnis yang lebih kompleks.
Ada bebrapa cara yang bisa dilakukan untuk melakukan validasi di NestJS, namun pada materi klai ini kita akan bahas dengan mengguankan class validator.
Dokumentasi resmi : https://docs.nestjs.com/pipes
Instalasi class-validator class-transformer
Pertama kita akan instalasi package yang dibutuhkan untuk menggunakan validasi.
Implementasikan validation pada DTO
Setelah instalasi selesai kita akan tambahkan validaton di DTO
import { OmitType } from "@nestjs/mapped-types";
import { IsInt, IsNotEmpty, Min, Max, Length } from "class-validator";
export class BookDto {
id: number;
@IsNotEmpty() // title tidak boleh kosong
@Length(4, 10) // panjang karakter dari title minimal 4 dan maksimal 10
title: string;
@IsNotEmpty()
author: string;
@IsInt() // year wajib number
@Min(2020) // minimal tahun adalah 2020
@Max(2023) //maksimal tahun adalah 2023
year: number;
}
export class CreateBookDto extends OmitType(BookDto, ["id"]) {}
export class UpdateBookDto extends OmitType(BookDto, ["id"]) {}
Pada kode di atas adalah contoh impelementasi class-validator
padda DTO sehingga kita bisa memastakan data yang dikirim oleh client sesuai dengan kriteria yang sudah di tentuakan. Selain decorator di atas masih banyak lagi decorator yang bisa kita gunakan pada project. Kita dapat membaca dokumentasi resmi nya di
https://github.com/typestack/class-validator#installation
Namun class Validator tidak akan bekerja sebelum kita implementasikan pipe
, pada contoh ini kita akan impelementasikan dulu validation pipe pada scope global. Hal yang harus kita lakukan adalah kita harus menambahkan validationPipe
pada main.ts
.
Implementasikan validation pada pipe global
main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { ValidationPipe } from "@nestjs/common"; //import
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe({ whitelist: true })); //implementasi
await app.listen(5002);
}
bootstrap();
Pengujian jika client mengirimkan year lebih dari 2023
Pengujian jika client mengirimkan panjang title kurang dari 4 karakter
Pengujian jika client mengirimkan sesuai dengan kriteria
2. Pipe Scope
Pada contoh di akan kita sudah mengimpelentasikan pipe global scope artinya validation akan diterapkan pada semua router hendler di controller. Ada beberapa cara dalam mengimpelentasikan pipe
Global scoped pipes
Pipe global Scope bertujuan bahwa setiap validation akan diterapkan pada semua route handler. Jika kita menggunakan pendekatan ini maka implementasinya seperti kode di atas pada main.ts
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { ValidationPipe } from "@nestjs/common"; //import
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe({ whitelist: true })); //implementasi
await app.listen(5002);
}
bootstrap();
Validation Controller
Pada pendekatan ini , kita hanya mengimpelentasikan validasi pada route tertentu saja. Namun untuk menerapkan ini kita perlu menghapus kode app.useGlobalPipes(new ValidationPipe()); pada main.ts. Selanjutkan kita akan coba implementaskan validation Contoller pada book.controller.ts
book.controller.ts
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
UsePipes,
ValidationPipe,
} from '@nestjs/common';
import { BookService } from './book.service';
import { CreateBookDto, UpdateBookDto } from './book.dto';
...
@Post('/create')
@UsePipes(ValidationPipe)
createBook(@Body() payload: CreateBookDto) {
return this.bookService.createBook(payload);
}
@Put('update/:id')
updateBook(@Param('id') id: string, @Body() updateBookDto: UpdateBookDto) {
return this.bookService.updateBook(Number(id), updateBookDto);
}
}
Pengujian pada create yang menggunakan Validation
Pengujian pada update yang tidak menggunakan Validation
Pada dua pendekatan di atas, saya lebih merekomendasikan menggunakan global scope agar kita cukup sekali pada main.ts, namun tidak menutup kemungkinana ada case-case yang mengharuskan kita bukan menggunakan global scope.