Express.js 5
  • Bab 2 dari 9
  • 20 menit
  • 4 soal kuis

Routing

Di bab ini (6 bagian)
  1. Tujuan
  2. Memahami Dasar Routing
  3. Parameter dan Sintaks Path di Express 5
  4. Query String dan Pagination
  5. Router Modular dengan express.Router()
  6. Rangkuman

Tujuan bab ini

Setelah menyelesaikan bab ini, kamu diharapkan mampu memahami dasar routing dan metode HTTP, menggunakan parameter path dan query string, serta menerapkan router modular menggunakan express.Router().

Routing adalah mekanisme utama dalam Express untuk merespons permintaan dari klien. Tanpa routing yang baik, aplikasi web hanya akan menjadi tumpukan kode yang membingungkan. Mari kita bedah satu per satu bagaimana Express menangani lalu lintas data ini secara elegan.

Memahami Dasar Routing

Dalam dunia Express, sebuah route adalah kombinasi dari metode HTTP, jalur URL (path), dan satu atau lebih fungsi handler. Kamu bisa membayangkan routing sebagai seorang resepsionis di sebuah gedung perkantoran. Ketika ada tamu (request) datang, resepsionis (router) akan melihat tujuan tamu tersebut (path URL) dan apa keperluannya (metode HTTP), lalu mengarahkannya ke ruangan yang tepat (handler).

Express mencocokkan route sesuai dengan urutan pendaftarannya di dalam kode. Artinya, jika ada dua route yang memiliki jalur yang sama persis, Express akan menjalankan route yang ditulis lebih dulu. Oleh karena itu, penulisan urutan kode sangatlah penting.

Metode HTTP dalam Express

Setiap route dikaitkan dengan metode HTTP tertentu yang mencerminkan maksud dari permintaan tersebut. Berikut adalah metode yang paling sering digunakan:

  • GET: Digunakan untuk mengambil data. Contohnya adalah saat kamu membuka halaman web atau meminta daftar produk.
  • POST: Digunakan untuk membuat data baru. Ini biasanya dipakai saat mengirim formulir pendaftaran atau menambahkan barang ke keranjang.
  • PUT: Digunakan untuk mengganti data secara utuh. Jika kamu menggunakan PUT, kamu mengirimkan seluruh representasi objek yang baru.
  • PATCH: Digunakan untuk mengubah data sebagian. Misalnya, kamu hanya ingin memperbarui status pesanan tanpa mengubah detail pesanan lainnya.
  • DELETE: Digunakan untuk menghapus data yang ada.

Selain mendefinisikan metode satu per satu seperti app.get() atau app.post(), Express menyediakan cara praktis untuk mengelompokkan beberapa metode pada satu jalur menggunakan app.route(). Jika kamu ingin satu handler dijalankan untuk semua metode pada jalur tertentu, kamu bisa menggunakan app.all().

Kesalahan yang sering terjadi bagi pemula adalah salah memilih antara PUT dan PATCH. Menggunakan PUT untuk pembaruan kecil bisa berisiko menghapus kolom lain jika data yang dikirim klien tidak lengkap. Oleh karena itu, biasakan menggunakan PATCH jika memang hanya sebagian data yang diperbarui.

Parameter dan Sintaks Path di Express 5

URL tidak selalu statis. Sering kali, kita perlu menangkap nilai dinamis dari URL, seperti ID pengguna atau nama kategori. Di sinilah parameter path berperan.

Express 5 membawa pembaruan besar pada cara kerja parameter path dengan menggunakan path-to-regexp v8. Sintaks ini dirancang agar lebih ketat dan aman, terutama untuk mencegah serangan manipulasi regex (ReDoS). Nilai yang ditangkap dari URL ini akan tersedia di dalam objek req.params.

Parameter Wajib dan Opsional

Untuk membuat parameter wajib, kamu cukup menambahkan titik dua sebelum nama parameter. Misalnya, pada rute /users/:id, jika seseorang mengakses /users/42, maka nilai req.params akan berisi { id: '42' }.

Di Express versi sebelumnya (v4), parameter opsional ditulis dengan tanda tanya seperti /:id?. Namun, di Express 5, sintaks tersebut tidak lagi didukung. Kamu harus menggunakan kurung kurawal untuk mendefinisikan bagian yang opsional, yaitu /users{/:id}. Dengan pola ini, rute akan cocok baik untuk /users (menghasilkan objek kosong {}) maupun /users/42.

Wildcard

Terkadang kamu perlu menangkap semua sisa jalur URL tanpa peduli seberapa panjang atau seberapa banyak segmen garis miringnya. Express 5 memperkenalkan wildcard bernama yang ditandai dengan *splat.

Misalnya, kamu mendefinisikan rute /files/*splat. Jika URL yang diakses adalah /files/a/b, maka Express akan memecah sisa jalur tersebut menjadi array, dan req.params akan berisi { splat: ['a', 'b'] }. Jika kamu butuh wildcard yang juga cocok untuk jalur dasar atau root, kamu bisa menggunakan /{*splat} yang akan cocok untuk / dan menghasilkan objek parameter kosong {}.

Satu hal penting yang perlu diingat adalah karakter regex dalam string path seperti tanda tanya, plus, bintang, atau kurung biasa tidak lagi didukung di Express 5. Jika kamu membutuhkan pencocokan pola yang kompleks, kamu harus mengirimkan objek RegExp secara langsung ke fungsi rute, contohnya app.get(/^\/v\d+$/, handler).

Query String dan Pagination

Selain parameter path, klien sering mengirimkan data tambahan melalui URL menggunakan query string. Bagian ini biasanya terletak setelah tanda tanya ? di akhir URL, seperti ?page=2&limit=10&q=kopi.

Express secara otomatis mem-parsing query string ini dan memasukkannya ke dalam objek req.query. Secara bawaan, parser yang digunakan adalah parser sederhana. Jika kamu membutuhkan objek bersarang yang kompleks (misalnya ?f[a]=1), kamu perlu mengatur konfigurasi aplikasi dengan perintah app.set('query parser', 'extended').

Sifat Read-Only pada Express 5

Ada perubahan perilaku yang cukup mendasar pada Express 5 terkait query string. Objek req.query sekarang bersifat read-only atau hanya bisa dibaca. Kamu tidak bisa lagi mengubah nilai req.query di tengah jalan secara langsung. Jika kamu perlu memanipulasi data query tersebut, kamu harus menyalinnya ke variabel baru.

Penting untuk disadari bahwa semua nilai di dalam req.query selalu berupa string. Jika kamu mengharapkan nilai angka, kamu wajib mengonversinya secara eksplisit menggunakan Number().

Hal ini sangat terasa saat kamu membuat fitur pencarian atau pagination. Saat menerima parameter limit atau page, kamu harus mengubah teks tersebut menjadi angka, dan sangat disarankan untuk memberikan batas maksimum menggunakan Math.min agar klien tidak bisa meminta data yang terlalu besar (misalnya meminta sejuta baris data sekaligus) yang dapat merusak kinerja server.

Router Modular dengan express.Router()

Saat aplikasi kamu berkembang, menuliskan puluhan atau ratusan rute di dalam file app.js akan membuat kode menjadi sulit dibaca dan dipelihara. Solusinya adalah memecah rute per fitur atau sumber daya (resource) agar mudah dirawat menggunakan router modular.

Kamu bisa menggunakan fungsi express.Router() untuk membuat router modular. Router ini bertindak seperti sebuah aplikasi Express mini. Ia memiliki sistem routing dan middleware sendiri yang terisolasi dari router lain.

Cara Kerja Router Modular

Misalnya, kamu sedang membangun fitur manajemen pengguna. Kamu bisa membuat file baru bernama routes/users.js, mendefinisikan router di sana, lalu mengekspornya. Di dalam file utama aplikasi, kamu cukup menggunakan app.use() untuk mendaftarkan router tersebut dengan prefix jalur tertentu. Prefix path ini cukup ditentukan satu kali saja saat memanggil app.use().

Keuntungan utama pendekatan ini adalah kode menjadi terisolasi. Jika ada bug di rute pengguna, kamu hanya perlu memeriksa file routes/users.js tanpa harus menyentuh fitur produk atau keranjang belanja.

Jika router modular kamu bersarang dan kamu perlu membaca parameter path yang didefinisikan oleh router induk (parent), kamu harus menginisialisasi router dengan opsi pewarisan parameter, yaitu Router({ mergeParams: true }).

Contoh Implementasi Routing Lengkap

Berikut adalah contoh bagaimana konsep router modular, metode HTTP, dan parameter diimplementasikan.

// src/routes/users.js
import { Router } from 'express';

// Mengaktifkan mergeParams agar bisa menangkap parameter dari root app
const router = Router({ mergeParams: true });

// Daftar user dengan query string (GET)
router.get('/', (req, res) => {
  // Salin dan konversi req.query karena bersifat read-only di v5
  const page = Number(req.query.page) || 1;
  const limit = Math.min(100, Number(req.query.limit) || 10);

  res.json({ message: 'Daftar user', page, limit });
});

// Membuat user baru (POST)
router.post('/', (req, res) => {
  res.status(201).json({ message: 'User dibuat' });
});

// Menangani satu user spesifik menggunakan app.route untuk meringkas kode
router.route('/:id')
  .get((req, res) => {
    res.json({ message: 'Detail user', id: req.params.id });
  })
  .put((req, res) => {
    res.json({ message: 'User diperbarui total', id: req.params.id });
  })
  .delete((req, res) => {
    res.json({ message: 'User dihapus', id: req.params.id });
  });

export default router;

Lalu di file utama aplikasi, kamu mendaftarkan router tersebut:

// src/app.js
import express from 'express';
import usersRouter from './routes/users.js';

const app = express();

// Mendaftarkan router users di bawah prefix /api/users
app.use('/api/users', usersRouter);

app.listen(3000, () => console.log('Server berjalan'));

Dengan memisahkan rute seperti di atas, aplikasi kamu akan jauh lebih terstruktur dan siap untuk diskalakan.

Rangkuman

  • Routing di Express memetakan metode HTTP (GET, POST, PUT, PATCH, DELETE) dan URL path ke fungsi handler tertentu sesuai dengan urutan pendaftaran.
  • Sintaks parameter path di Express 5 lebih ketat; parameter opsional ditulis menggunakan kurung kurawal /{:id} dan wildcard berbentuk array menggunakan /*splat.
  • Karakter regex biasa di dalam string path tidak lagi didukung di Express 5, kamu harus memakai objek RegExp asli untuk pencocokan kompleks.
  • Data dari query string tersedia di req.query, yang selalu berisi string dan bersifat read-only (tidak dapat diubah langsung) di Express 5.
  • Untuk menjaga kode tetap rapi, gunakan express.Router() guna memecah rute menjadi modul-modul kecil berdasarkan fitur, di mana prefix path didaftarkan lewat app.use().
  • Gunakan opsi mergeParams: true pada inisialisasi router jika router anak perlu membaca parameter path dari router induknya.

Selesaikan bab ini

  1. 1. Baca materi
  2. 2. Kuis (4 soal)

Cek pemahaman

  1. 1Bagaimana cara penulisan sintaks parameter opsional yang benar pada path di Express 5?

  2. 2Pada Express 5, kamu bisa langsung mengubah atau menimpa nilai properti di dalam objek req.query di tengah jalannya request.

  3. 3Metode HTTP mana yang secara semantik paling tepat digunakan untuk mengubah sebagian data dari suatu resource (misalnya hanya mengubah status pesanan)?

  4. 4Berdasarkan kode di bawah ini, apa yang akan ada di dalam req.params.splat apabila klien mengakses URL `/files/dokumen/laporan.pdf`?

    app.get('/files/*splat', (req, res) => {
      res.json(req.params.splat);
    });