Express.js 5
  • Bab 4 dari 9
  • 20 menit
  • 1 latihan kode
  • 4 soal kuis

Request, Response & Error

Di bab ini (6 bagian)
  1. Tujuan
  2. Membaca Input dengan Objek Request (req)
  3. Mengirim Output dengan Objek Response (res)
  4. Penanganan Error Async di Express 5
  5. Server-Side Rendering dengan Template Engine
  6. Rangkuman

Tujuan bab ini

Bab ini memiliki beberapa tujuan utama untuk memperdalam pemahaman kamu tentang Express. Fokus pertama adalah membaca objek request dan mengirim response dengan tepat. Selanjutnya, kita akan membahas cara menangani error asynchronous secara otomatis yang merupakan fitur andalan di Express 5. Terakhir, kamu akan mempelajari cara menggunakan template engine untuk kebutuhan server-side rendering.

Membaca Input dengan Objek Request (req)

Dalam Express, setiap kali ada permintaan dari klien, fungsi handler kamu akan menerima objek request, yang sering disingkat sebagai req. Objek ini menyimpan semua informasi tentang permintaan tersebut. Mari kita bedah properti yang paling sering dipakai.

Mengambil Data dari URL

Seringkali, informasi penting dikirimkan langsung melalui URL. Ada dua cara utama klien mengirim data via URL, yaitu melalui parameter path dan query string.

Properti req.params digunakan untuk menangkap parameter dinamis pada path atau rute. Misalnya, jika kamu memiliki rute /users/:id, nilai dari :id tersebut akan secara otomatis tersedia di dalam req.params.id. Ini sangat berguna saat kamu ingin mengambil detail dari satu sumber daya spesifik.

Selain parameter path, ada juga req.query yang bertugas menangkap data dari query string. Query string adalah bagian dari URL yang dimulai dengan tanda tanya, seperti ?page=2. Di Express 5, properti req.query ini bersifat read-only atau hanya-baca, yang berarti kamu tidak bisa lagi menimpanya secara langsung di dalam kode kamu. Jika kamu perlu mengubah nilainya, salin dulu ke variabel baru.

Membaca Body dan Header

Untuk data yang lebih kompleks seperti formulir atau payload JSON, klien biasanya mengirimkannya melalui body request. Kamu bisa mengaksesnya menggunakan properti req.body. Perlu dicatat bahwa secara bawaan Express tidak tahu cara membaca body, sehingga kamu harus menambahkan middleware parser terlebih dahulu, seperti express.json(), agar req.body bisa terisi data yang benar.

Selain body, klien juga kerap mengirimkan informasi tambahan melalui header HTTP. Kamu bisa membaca nilai header tertentu dengan menggunakan fungsi req.get('Header'). Misalnya, req.get('Authorization') sering digunakan untuk mengambil token akses.

Beberapa informasi terkait jaringan dan lokasi rute juga tersedia. Properti req.ip memberikan alamat IP dari klien yang melakukan permintaan, sedangkan req.path memberikan jalur URL spesifik dari request tersebut. Terakhir, jika kamu menggunakan middleware cookie-parser, kamu bisa membaca data cookie yang dikirim oleh klien melalui properti req.cookies.

Mengirim Output dengan Objek Response (res)

Setelah memproses request, tugas server selanjutnya adalah mengirimkan balasan kembali ke klien. Hal ini dilakukan melalui objek response atau res.

Mengatur Status dan Mengirim Data

Metode res.status(code) digunakan untuk mengatur status HTTP dari balasan kamu. Status ini penting agar klien tahu apakah permintaannya berhasil, gagal, atau butuh tindakan lain. Misalnya, kamu bisa memakai status 201 untuk data yang baru dibuat, atau 404 untuk rute yang tidak ditemukan.

Untuk mengirim datanya sendiri, ada beberapa pilihan. Jika kamu membangun sebuah REST API, metode yang paling umum digunakan adalah res.json(obj). Metode ini akan mengubah objek JavaScript menjadi format JSON dan mengirimkannya ke klien beserta header yang sesuai. Jika kamu ingin mengirimkan teks biasa, HTML mentah, atau data berbentuk Buffer, kamu bisa menggunakan res.send(data).

Navigasi dan Manajemen File

Ada kalanya klien meminta suatu rute, namun kamu ingin mengarahkannya ke rute lain. Kamu bisa memanggil res.redirect(url) untuk mengalihkan klien secara otomatis ke URL yang baru.

Bila aplikasimu bertugas menyajikan file, seperti gambar atau dokumen PDF, gunakan metode res.sendFile(path). Pastikan kamu memberikan path absolut dari sistem operasi kamu agar Express bisa menemukan file tersebut dengan benar.

Terkait manajemen informasi penyerta, kamu bisa mengubah header dari response menggunakan res.set(). Sedangkan untuk menanamkan cookie ke browser klien, kamu cukup memanggil metode res.cookie().

Penanganan Error Async di Express 5

Salah satu pembaruan paling signifikan yang dibawa oleh Express versi 5 adalah cara framework ini menangani error pada kode asynchronous. Ini membedakannya dari Express versi 4 dan membuat kodemu menjadi jauh lebih bersih.

Menghilangkan try/catch Manual

Pada versi sebelumnya, jika kamu menggunakan fungsi asynchronous dan terjadi error (misalnya database gagal dihubungi), error tersebut akan membuat aplikasi menggantung jika tidak ditangkap. Kamu diwajibkan membungkus semuanya dengan blok try/catch dan secara manual meneruskan error tersebut ke middleware berikutnya menggunakan next(err).

Di Express 5, pendekatan itu tidak lagi diperlukan. Promise yang mengalami penolakan (reject) akan secara otomatis diteruskan ke error handler. Kamu bisa langsung melempar error di dalam fungsi async tanpa memerlukan try/catch sama sekali.

Berikut adalah contoh bagaimana error async ditangani beserta penerapan middleware error di Express 5.

// utils/AppError.js
export class AppError extends Error {
  constructor(status, message) {
    super(message);
    this.status = status;
  }
}

// app.js
// Promise yang reject otomatis diteruskan ke error handler tanpa try/catch
app.get('/users/:id', async (req, res) => {
  const user = await db.findUser(req.params.id);
  if (!user) throw new AppError(404, 'User tidak ditemukan');
  res.json(user);
});

// 404 untuk route yang tidak ada
app.use((req, res) => res.status(404).json({ error: 'Not Found' }));

// Error handler: 4 argumen, didaftarkan paling akhir
app.use((err, req, res, next) => {
  const status = err.status ?? 500;
  if (status >= 500) console.error(err);
  res.status(status).json({
    error: status >= 500 ? 'Terjadi kesalahan server' : err.message,
  });
});

Memahami Middleware Error

Dalam contoh di atas, kita melihat dua penangan error di akhir aplikasi. Yang pertama adalah penangan 404. Ini adalah middleware biasa yang akan dieksekusi jika tidak ada rute di atasnya yang cocok dengan request klien.

Yang kedua adalah error handler sesungguhnya. Middleware error memiliki ciri khas yang sangat spesifik, yaitu harus memiliki tepat empat argumen: (err, req, res, next). Keempat argumen ini wajib ada agar Express mengenali fungsi tersebut sebagai penangan error, bukan middleware biasa. Posisi middleware ini juga krusial, ia harus didaftarkan paling akhir setelah semua rute dan middleware lainnya.

Dalam penulisan penangan error untuk sistem produksi, usahakan agar pesan umum diberikan untuk error 5xx dan detail error (seperti stack trace) hanya dicatat di log server internal agar tidak bocor ke publik.

Server-Side Rendering dengan Template Engine

Express tidak hanya diperuntukkan bagi pembuatan REST API yang membalas dengan JSON. Framework ini juga sangat andal digunakan untuk menyajikan halaman HTML utuh ke browser klien melalui teknik server-side rendering (SSR).

Untuk melakukan ini, Express membutuhkan bantuan template engine. Template engine adalah alat yang memungkinkan kamu menyisipkan variabel dan logika pemrograman ke dalam file mirip HTML, yang nantinya akan diproses menjadi HTML sungguhan sebelum dikirim ke klien.

Ada beberapa pilihan template engine yang populer di ekosistem Node.js:

  • EJS: Memiliki sintaks yang sangat mirip dengan HTML biasa ditambah dengan tag khusus untuk menyisipkan JavaScript. Sangat ramah untuk pemula.
  • Pug: Menawarkan sintaks yang ringkas dan sangat bergantung pada tingkat indentasi, mirip dengan Python.
  • Handlebars: Dikenal sebagai template engine logic-less (minim logika), menjadikannya pilihan yang sangat cocok dan aman untuk membuat template email.

Berikut adalah contoh penggunaan EJS di Express.

// app.js
// pastikan ejs sudah diinstal via npm
app.set('view engine', 'ejs');
app.set('views', './views');

app.get('/profil', (req, res) => {
  res.render('profil', {
    nama: 'Budi',
    hobi: ['coding', 'futsal']
  });
});

File EJS-nya sendiri akan terlihat seperti campuran HTML dan perulangan JavaScript.

<!-- views/profil.ejs -->
<h1>Halo, <%= nama %>!</h1>
<ul>
  <% hobi.forEach(h => { %>
    <li><%= h %></li>
  <% }) %>
</ul>

Saat pengguna mengakses rute /profil, Express akan memanggil res.render() untuk membaca file profil.ejs, mengeksekusi kode perulangan di dalamnya, memasukkan nama "Budi", lalu mengirimkan hasil akhir berupa HTML ke browser.

Rangkuman

  • Objek request (req) dipakai untuk membaca input seperti rute dinamis via req.params, query string via req.query, atau data payload via req.body.
  • Objek response (res) dipakai untuk membalas klien, contohnya res.json() untuk API atau res.status() untuk menetapkan kode HTTP.
  • Express 5 secara otomatis menangkap Promise yang reject pada handler async dan meneruskannya ke error handler, menghapus keharusan blok try/catch manual.
  • Middleware penangan error dikenali dari jumlah argumennya yang berjumlah empat (err, req, res, next) dan harus diletakkan paling bawah.
  • Express mendukung penyajian HTML dinamis lewat server-side rendering menggunakan template engine seperti EJS, Pug, dan Handlebars.

Selesaikan bab ini

  1. 1. Baca materi
  2. 2. Latihan kode (1)
  3. 3. Kuis (4 soal)

Latihan kode: Endpoint Sederhana Express

Buat dua rute menggunakan Express.

  1. Rute GET /ping yang mengirimkan response berupa JSON {"pesan": "pong"}.
  2. Rute GET /data/:id yang mengambil parameter ID dari path dan mengirimkan response berupa JSON {"idData": "<nilai_id>"}.

Cek pemahaman

  1. 1Properti apa pada objek request yang nilainya kini bersifat read-only (hanya-baca) di Express 5?

  2. 2Di Express 5, kita masih diwajibkan menulis try/catch secara manual pada setiap rute asynchronous untuk meneruskan error ke middleware penangan error.

  3. 3Apa syarat utama agar sebuah middleware dikenali oleh Express sebagai error handler?

  4. 4Template engine manakah yang direkomendasikan untuk template email karena karakternya yang logic-less (minim logika)?