Yuk, Kamu Coba Bikin URL Shortener Pakai NestJS, MongoDB, dan Docker

Yuk, Kamu Coba Bikin URL Shortener Pakai NestJS, MongoDB, dan Docker
Photo by Sean Foster/Unsplash

Yuk, Kamu Coba Bikin URL Shortener Pakai NestJS, MongoDB, dan Docker

Pernah nggak sih kamu ngerasa link URL itu kadang kepanjangan banget, apalagi kalau mau di-share di media sosial atau presentasi? Nah, di sinilah peran URL shortener jadi penting. Bayangin aja, link yang tadinya sepanjang rel kereta api bisa jadi cuma beberapa karakter doang. Keren, kan?

Di artikel ini, kita bakal bongkar tuntas gimana caranya bikin URL shortener sendiri. Nggak cuma pakai satu teknologi, tapi kita mau gabungin tiga teknologi kekinian yang powerful banget: NestJS buat backend-nya, MongoDB buat databasenya, dan Docker buat packaging dan deployment-nya. Dijamin setelah ini, kamu bakal punya skill baru yang bisa dipamerin!

Kenalan Sama Teknologi Keren Kita: NestJS, MongoDB, dan Docker

Sebelum kita mulai "ngoprek" kodenya, yuk kenalan dulu sama tiga pahlawan kita ini. Biar akrab, gitu.

1. NestJS: Framework Node.js yang Modern dan Rapi Mungkin kamu udah familiar sama Node.js. NestJS ini adalah framework buat Node.js yang dibangun dengan TypeScript. Kalau kamu suka Angular, kamu pasti langsung akrab sama struktur NestJS karena memang terinspirasi dari sana.

  • Kenapa NestJS? NestJS itu bikin aplikasi Node.js kamu jadi lebih terstruktur, modular, dan gampang di-maintain. Ini penting banget, apalagi kalau proyek kamu makin gede. Dia ngasih kita "aturan main" yang jelas, jadi semua tim bisa kerja bareng tanpa tabrakan. NestJS juga punya fitur-fitur bawaan yang berguna banget kayak dependency injection, validation, dan modulasi yang kuat. Pokoknya, buat bikin API yang scalable dan maintainable, NestJS ini pilihan yang ciamik.

2. MongoDB: Database NoSQL yang Fleksibel Banget Pernah dengar SQL dan NoSQL? Nah, MongoDB ini salah satu primadona di dunia NoSQL. Beda sama database SQL yang pakai tabel dan skema ketat, MongoDB itu pakai dokumen mirip JSON (namanya BSON) buat nyimpen data.

  • Kenapa MongoDB? Fleksibilitasnya itu lho yang bikin jatuh hati. Kamu nggak perlu pusing mikirin skema database di awal proyek. Kalau data kamu butuh berubah strukturnya di tengah jalan, MongoDB bisa dengan mudah mengakomodasi itu. Ini cocok banget buat proyek yang masih berkembang atau punya data dengan struktur yang beragam. Plus, integrasinya sama Node.js itu mulus banget, jadi proses development jadi lebih cepat.

3. Docker: Jaminan "Works on My Machine" Itu Nyata! Pasti sering dengar kan keluhan developer "kok di komputer saya jalan, di komputer kamu nggak?". Nah, Docker datang sebagai penyelamat. Docker ini teknologi containerization. Ibaratnya, dia itu bikin kotak spesial yang isinya aplikasi kamu dan semua "perabot" yang dia butuhin (library, dependency, environment).

  • Kenapa Docker? Dengan Docker, aplikasi kamu bisa jalan di mana aja, di komputer siapa aja, dengan hasil yang konsisten. Nggak peduli OS-nya Windows, macOS, atau Linux, selama ada Docker, aplikasi kamu bakal jalan persis sama. Ini juga memudahkan banget proses deployment ke server production. Nggak ada lagi drama perbedaan lingkungan.

Udah kenalan kan? Sekarang, yuk kita siap-siap buat ngoding!

Persiapan Tempur: Apa Aja yang Dibutuhin?

Sebelum kita mulai nulis kode, ada beberapa peralatan yang perlu kamu siapkan:

  • Node.js dan npm/yarn: Ini wajib punya karena NestJS itu framework Node.js. Kamu bisa download di website resminya.
  • Docker Desktop: Instal Docker Desktop sesuai OS kamu (Windows, macOS, Linux). Ini yang bakal kita pakai buat menjalankan MongoDB dan aplikasi NestJS kita dalam container.
  • IDE (Integrated Development Environment): VS Code itu pilihan favorit banyak developer karena ringan dan banyak extension-nya.
  • Git (opsional, tapi sangat disarankan): Buat version control, biar kode kamu aman dan rapi.

Udah siap semua? Gas!

Ngebut Bikin Proyek NestJS-nya

Langkah pertama, kita bikin proyek NestJS baru. Gampang banget kok:

  1. Instal NestJS CLI:

Buka terminal atau command prompt kamu, lalu ketik ini:

bash
    npm install -g @nestjs/cli

Ini buat nginstal command-line interface NestJS secara global di komputer kamu, biar gampang bikin proyek dan generate file-file NestJS.

  1. Buat Proyek Baru:

Setelah CLI terinstal, bikin proyek URL shortener kita:

bash
    nest new url-shortener-app

NestJS CLI akan nanya kamu mau pakai package manager apa (npm atau yarn). Pilih aja npm untuk konsistensi di artikel ini. Tunggu sampai proses instalasi dependensi selesai.

  1. Jalanin Aplikasinya:

Masuk ke folder proyek yang baru kamu buat:

bash
    cd url-shortener-app

Lalu jalankan aplikasi dalam mode development:

bash
    npm run start:dev

Harusnya kamu akan melihat pesan bahwa aplikasi berjalan di http://localhost:3000. Coba buka di browser, kalau muncul tulisan "Hello World!", berarti NestJS kamu udah siap!

Integrasi MongoDB (Pakai Mongoose)

Sekarang, kita mau konekin NestJS kita sama MongoDB. Untuk mempermudah, kita bakal pakai Mongoose, sebuah ODM (Object Data Modeling) library buat MongoDB di Node.js.

  1. Instal Mongoose di NestJS:

Berhenti dulu server NestJS (Ctrl+C), lalu install package yang dibutuhkan:

bash
    npm install --save @nestjs/mongoose mongoose
  1. Konfigurasi Koneksi Database:

Buka file src/app.module.ts. Ini adalah "otak" utama aplikasi NestJS kita. Kita akan impor MongooseModule dan mengkonfigurasinya.

typescript
    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { MongooseModule } from '@nestjs/mongoose'; // Import MongooseModule
    import { ShortUrlModule } from './short-url/short-url.module'; // Nanti kita buat ini

Perhatikan string koneksi mongodb://localhost/url-shortener-db. Ini berarti kita mencoba terhubung ke MongoDB yang berjalan di localhost (komputer kita sendiri) dengan nama database url-shortener-db.

  1. Bikin Modul, Skema, dan Model URL Shortener:

Kita mau bikin struktur data buat URL pendek kita. Setiap URL pendek bakal punya originalUrl (URL aslinya) dan shortCode (kode pendeknya).

* Buat Modul ShortUrl:

bash
        nest generate module short-url

Ini akan membuat folder src/short-url dan src/short-url/short-url.module.ts.

* Buat Skema MongoDB: Buat file baru di src/short-url/schemas/short-url.schema.ts (kamu perlu bikin folder schemas di dalam short-url):

typescript
        import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
        import { Document } from 'mongoose';export type ShortUrlDocument = ShortUrl & Document;@Schema({ timestamps: true }) // Tambahin timestamps biar otomatis ada createdAt dan updatedAt
        export class ShortUrl {
          @Prop({ required: true, unique: true })
          shortCode: string; // Kode pendek unik@Prop({ required: true })
          originalUrl: string; // URL aslinya@Prop({ default: 0 })
          visits: number; // Jumlah kunjungan, default 0
        }

* Buat Service:

bash
        nest generate service short-url

Ini akan membuat src/short-url/short-url.service.ts. Edit isinya seperti ini:

typescript
        import { Injectable, NotFoundException } from '@nestjs/common';
        import { InjectModel } from '@nestjs/mongoose';
        import { Model } from 'mongoose';
        import { ShortUrl, ShortUrlDocument } from './schemas/short-url.schema';
        import { nanoid } from 'nanoid'; // Kita akan install nanoid nanti@Injectable()
        export class ShortUrlService {
          constructor(
            @InjectModel(ShortUrl.name) private shortUrlModel: Model,
          ) {}async shortenUrl(originalUrl: string): Promise {
            // Generate short code unik (misal 7 karakter)
            const shortCode = nanoid(7);
            const newShortUrl = new this.shortUrlModel({ originalUrl, shortCode });
            return newShortUrl.save();
          }async getOriginalUrl(shortCode: string): Promise {
            const shortUrl = await this.shortUrlModel.findOne({ shortCode }).exec();
            if (!shortUrl) {
              throw new NotFoundException('Short URL not found');
            }
            // Tambah jumlah kunjungan
            shortUrl.visits++;
            await shortUrl.save();
            return shortUrl.originalUrl;
          }

Jangan lupa install nanoid buat generate kode unik: npm install nanoid.

* Buat Controller:

bash
        nest generate controller short-url

Ini akan membuat src/short-url/short-url.controller.ts. Edit isinya:

typescript
        import { Body, Controller, Get, Param, Post, Redirect } from '@nestjs/common';
        import { ShortUrlService } from './short-url.service';
        import { CreateShortUrlDto } from './dto/create-short-url.dto'; // Nanti kita buat ini@Controller('short-urls') // Endpoint utama
        export class ShortUrlController {
          constructor(private readonly shortUrlService: ShortUrlService) {}@Post()
          async createShortUrl(@Body() createShortUrlDto: CreateShortUrlDto) {
            const shortUrl = await this.shortUrlService.shortenUrl(createShortUrlDto.originalUrl);
            return {
              originalUrl: shortUrl.originalUrl,
              shortCode: shortUrl.shortCode,
              shortenedUrl: http://localhost:3000/${shortUrl.shortCode}, // URL pendek lengkap
            };
          }

Kita butuh DTO (Data Transfer Object) buat validasi input. Buat file src/short-url/dto/create-short-url.dto.ts:

typescript
        import { IsUrl, IsNotEmpty } from 'class-validator';

Untuk validasi, kamu perlu install class-validator dan class-transformer:

bash
        npm install --save class-validator class-transformer

Dan aktifkan ValidationPipe di main.ts:

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

* Update short-url.module.ts: Terakhir, kita perlu daftarin semua ini ke modul kita. Edit src/short-url/short-url.module.ts:

typescript
        import { Module } from '@nestjs/common';
        import { ShortUrlService } from './short-url.service';
        import { ShortUrlController } from './short-url.controller';
        import { MongooseModule } from '@nestjs/mongoose';
        import { ShortUrl, ShortUrlSchema } from './schemas/short-url.schema';

Sampai sini, aplikasi NestJS kita udah siap menerima permintaan shorten URL dan melakukan redirect. Tapi MongoDB-nya belum jalan, dan kita mau pakai Docker biar semuanya rapi.

Bikin Dockerfile Buat Aplikasi NestJS Kita

Sekarang kita mau "bungkus" aplikasi NestJS kita ke dalam Docker container. Caranya, kita buat file Dockerfile di root folder proyek kita (sejajar dengan package.json).

dockerfile
Tahap 1: Build tahap (untuk install dependensi dan compile TypeScript)
FROM node:lts-alpine as builderSet working directory di dalam container
WORKDIR /appCopy package.json dan package-lock.json (atau yarn.lock)
untuk memastikan dependensi diinstal dengan benar
COPY package*.json ./Instal semua dependensi
RUN npm installCopy sisa kode aplikasi ke dalam container
COPY . .Build aplikasi NestJS (compile TypeScript ke JavaScript)
RUN npm run buildTahap 2: Tahap produksi (menjalankan aplikasi yang sudah di-build)
FROM node:lts-alpineSet working directory lagi untuk tahap produksi
WORKDIR /appCopy hanya node_modules dari builder stage (lebih efisien)
COPY --from=builder /app/nodemodules ./nodemodulesCopy hasil build aplikasi dari builder stage
COPY --from=builder /app/dist ./distExposed port yang akan digunakan aplikasi
EXPOSE 3000Perintah untuk menjalankan aplikasi ketika container dimulai
CMD ["node", "dist/main"]

Dockerfile ini pakai multi-stage build, artinya ada dua tahap: satu buat build aplikasi (instalasi dan kompilasi), satu lagi buat running aplikasi (hanya butuh hasil kompilasi dan dependensi). Ini bikin ukuran image Docker kamu jadi lebih kecil dan efisien.

Ngegabungin Semuanya Pake Docker Compose

Docker Compose itu alat yang super power buat ngatur aplikasi multi-container. Kita punya dua container yang perlu jalan: satu buat aplikasi NestJS kita, satu lagi buat MongoDB.

Buat file docker-compose.yml di root folder proyek kamu:

yaml
version: '3.8' # Versi Docker Composeservices:
  # Service untuk aplikasi NestJS kita
  app:
    build:
      context: . # Konteks build dari folder proyek saat ini
      dockerfile: Dockerfile # Gunakan Dockerfile yang sudah kita buat
    ports:
      - "3000:3000" # Mapping port: HostPort:ContainerPort
    depends_on:
      - mongo # Pastikan container mongo jalan duluan
    environment:
      # Variabel lingkungan untuk koneksi ke MongoDB (nama service mongo)
      MONGODB_URI: "mongodb://mongo:27017/url-shortener-db"
    # Restart kebijakan, coba restart jika gagal
    restart: always# Service untuk database MongoDB
  mongo:
    image: mongo:latest # Gunakan image MongoDB terbaru
    ports:
      - "27017:27017" # Opsional: mapping port untuk akses MongoDB dari host
    volumes:
      # Persistent storage untuk data MongoDB, biar data nggak hilang kalau container di-destroy
      - mongo-data:/data/db
    restart: always

Penting: Di src/app.module.ts tadi kita pakai mongodb://localhost/url-shortener-db. Nah, kalau pakai Docker Compose, localhost di dalam container app itu beda sama localhost di host kamu. Untuk komunikasi antar container, kita pakai nama service-nya. Jadi, dari container app, MongoDB bisa diakses lewat mongo (nama service-nya). Makanya kita pakai MONGODB_URI di docker-compose.yml dan di NestJS-nya, kita ganti konfigurasi MongooseModule-nya sedikit:

Buka src/app.module.ts lagi, dan ubah bagian MongooseModule.forRoot jadi seperti ini:

typescript
// ...import lainnya
import { ConfigModule } from '@nestjs/config'; // Import ConfigModule

Sekarang, aplikasi kita akan membaca MONGODB_URI dari environment variable. Kalau di Docker Compose kita set, dia bakal pakai itu. Kalau nggak (misal pas development tanpa Docker), dia bakal fallback ke localhost.

Jangan lupa install @nestjs/config: npm install @nestjs/config.

Jalanin Semuanya dengan Docker Compose!

Ini dia momen yang ditunggu-tunggu! Buka terminal di root folder proyek kamu, lalu jalankan:

bash
docker-compose up --build

Perintah ini akan:

  1. Membangun image Docker untuk aplikasi NestJS kamu berdasarkan Dockerfile.
  2. Mendownload image MongoDB (kalau belum ada).
  3. Membuat dan menjalankan kedua container (app dan mongo).

Tunggu sampai semua proses selesai. Harusnya kamu akan melihat log dari kedua container. Kalau sudah, aplikasi NestJS kamu seharusnya jalan di http://localhost:3000.

Verifikasi:

  • Coba buka http://localhost:3000 di browser. Seharusnya muncul pesan "Hello World!".
  • Untuk mengetes URL shortener-nya, kamu bisa pakai Postman atau Insomnia, atau bahkan curl:
bash
    curl -X POST -H "Content-Type: application/json" -d '{"originalUrl": "https://www.google.com"}' http://localhost:3000/short-urls

Kamu akan dapat respons JSON yang berisi shortenedUrl. Coba akses shortenedUrl itu di browser, harusnya langsung di-redirect ke Google!

  • Coba akses URL pendek yang nggak ada (misal http://localhost:3000/xyzabc), harusnya muncul NotFoundException.

Selamat! Kamu berhasil bikin URL shortener pakai NestJS, MongoDB, dan Docker!

Tips dan Trik Tambahan (Biar Makin Jago)

Setelah berhasil bikin core-nya, ada beberapa hal lagi yang bisa kamu eksplor biar URL shortener kamu makin canggih:

  1. Custom Short Code: Biarkan user bisa request kode pendeknya sendiri (misal: http://localhost:3000/namasaya). Pastikan kodenya unik dan validasinya ketat.
  2. Analytics: Tambahin fitur buat ngitung berapa kali sebuah URL pendek diakses, atau dari mana asalnya. Kamu bisa nambahin field di skema MongoDB (misal: visits, lastVisitedAt).
  3. Authentication dan Authorization: Kalau kamu mau aplikasi ini hanya bisa dipakai user tertentu, tambahkan sistem login (pakai JWT misalnya) dan batasi akses API-nya.
  4. Rate Limiting: Penting buat mencegah penyalahgunaan atau serangan DDOS. NestJS punya modul ThrottlerModule yang bisa kamu pakai.
  5. Environment Variables yang Lebih Canggih: Untuk konfigurasi yang lebih banyak (misal: port, string koneksi, secret keys), pakai file .env dan baca dengan @nestjs/config.
  6. Deployment ke Produksi: Kalau udah siap, kamu bisa deploy aplikasi ini ke platform cloud seperti Heroku, Vercel (untuk NestJS-nya), AWS ECS, Google Cloud Run, atau bahkan VPS biasa. Docker Compose ini sangat membantu banget proses deployment jadi lebih mudah.
  7. Testing: Tulis unit test dan end-to-end test buat memastikan semua fitur berjalan sesuai harapan dan nggak ada bug saat ada perubahan kode.

Penutup

Gimana? Seru kan bikin aplikasi dengan teknologi modern kayak NestJS, MongoDB, dan Docker? Kamu udah belajar gimana cara setup proyek, integrasi database NoSQL, sampai akhirnya bisa nge-package semuanya dalam container biar gampang di-deploy.

Skill ini fundamental banget di dunia development modern. Dengan menguasai kombinasi teknologi ini, kamu udah selangkah lebih maju buat jadi developer yang handal. Jangan berhenti di sini! Coba eksplorasi lebih jauh fitur-fitur yang ada, tambahkan fungsionalitas, atau bahkan bangun proyek lain dengan stack yang sama. Proses belajar itu nggak ada habisnya, jadi teruslah ngoprek dan berkreasi! Siapa tahu, URL shortener bikinan kamu bisa jadi solusi next level yang dipakai banyak orang!