Episode ini membedah arsitektur inti NestJS: bagaimana framework bekerja di balik layar sebagai wrapper Express, peran module-controller-provider, dependency injection container, lifecycle aplikasi, serta komponen pipes, guards, filters, dan interceptors.

Setelah memahami mengapa NestJS ada, sekarang kita masuk ke bagaimana NestJS bekerja. Arsitektur NestJS bisa terlihat rumit di awal karena banyaknya istilah: module, controller, provider, pipe, guard, filter, interceptor. Padahal semuanya mengikuti satu pola yang konsisten.
Episode 2 membedah konsep dasar dan arsitektur utama NestJS. Kalian akan memahami peran setiap komponen, cara dependency injection bekerja, serta alur hidup aplikasi dari bootstrap sampai merespons request.
Secara default, NestJS membungkus Express — NestJS tidak menggantikan Express, melainkan berjalan di atasnya. Kalian tetap bisa mengakses objek req dan res milik Express saat dibutuhkan. NestJS juga mendukung Fastify sebagai alternatif yang lebih cepat.
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap(): Promise<void> {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
void bootstrap();Fungsi bootstrap() ini adalah pintu masuk aplikasi. NestFactory.create membuat instance aplikasi dan app.listen(3000) menjalankan server HTTP di balik layar — Express secara default.
NestJS memiliki lifecycle yang jelas: module dan provider diinisialisasi saat aplikasi start, lalu hook seperti OnModuleInit dan OnModuleDestroy bisa dipakai untuk menjalankan kode pada tahap tertentu — misalnya membuka koneksi database atau menutupnya saat shutdown.
Module adalah unit organisasi utama. Setiap aplikasi memiliki root module (AppModule), dan fitur dipecah menjadi feature module. Module mendeklarasikan controller, provider, dan module lain yang diimpor.
Controller bertanggung jawab menerima request dan mengembalikan response. Controller tidak berisi logika bisnis — dia meneruskan pekerjaan ke service. Routing didefinisikan lewat dekorator seperti @Get dan @Post.
import { Controller, Get } from "@nestjs/common";
@Controller("users")
export class UserController {
@Get()
findAll(): string[] {
return ["Arman", "Budi"];
}
}Dekorator @Controller("users") menetapkan prefix route, dan @Get() menetapkan bahwa method ini merespons request GET ke /users.
Provider adalah class yang berisi logika aplikasi — biasanya disebut service. Provider didaftarkan di module dan disuntikkan ke controller atau provider lain lewat dependency injection.
NestJS memiliki dependency injection container yang mengelola pembuatan dan penyuntikan provider. Saat sebuah controller meminta service di constructor-nya, NestJS yang membuat instance service tersebut dan menyuntikkannya secara otomatis.
@Controller("users")
export class UserController {
constructor(private readonly userService: UserService) {}
}Perhatikan bahwa UserService tidak dibuat manual — cukup dideklarasikan di constructor, NestJS yang menanganinya. Ini disebut constructor injection.
Container menyelesaikan dependensi secara berurutan: jika UserService sendiri membutuhkan DatabaseService, container membuat DatabaseService dulu, lalu UserService, baru kemudian controller. Graph dependensi ini dibangun saat aplikasi start.
Pipe memvalidasi dan mentransformasi data yang masuk sebelum mencapai handler. Contoh bawaan: ValidationPipe dan ParseIntPipe.
Guard menentukan apakah sebuah request boleh dilanjutkan, biasanya untuk autentikasi dan otorisasi. Guard berjalan sebelum pipe dan handler.
Exception filter menangkap error dan mengubahnya menjadi response yang rapi. Filter default menghasilkan response JSON dengan status code yang sesuai.
Interceptor membungkus eksekusi handler — bisa menambah logika sebelum dan sesudah handler, mengubah response, atau menangani caching. Ini pola yang kuat untuk cross-cutting concern.
Nest CLI sudah menghasilkan struktur yang rapi sejak awal:
src/
main.ts
app.module.ts
app.controller.ts
app.service.tsSetiap fitur nanti punya folder sendiri, misalnya users/ yang berisi users.module.ts, users.controller.ts, dan users.service.ts.
Module bisa mengekspor provider agar dipakai module lain (shared module), atau ditandai @Global() agar tersedia di seluruh aplikasi tanpa perlu diimpor berulang kali. Kedua pola ini menjaga keseimbangan antara struktur dan kepraktisan.
Episode 2 memberi kalian peta lengkap arsitektur NestJS: NestJS berjalan di atas Express, diorganisir dalam module, controller, dan provider, serta dikelola oleh dependency injection container. Komponen pipes, guards, filters, dan interceptors menangani kebutuhan cross-cutting.
Inti yang harus dibawa pulang:
OnModuleInit dan OnModuleDestroy.Di episode 3 selanjutnya kita akan membahas memulai aplikasi pertama — membuat project dengan Nest CLI, memahami struktur src/app.module.ts dan main.ts, menjalankan aplikasi, memeriksa endpoint dasar, serta konfigurasi awal memakai @nestjs/config.