Routing adalah cara Express memilih kode mana yang menjawab sebuah request, berdasarkan method dan path-nya. Bayangin resepsionis gedung kantor. Tamu datang dan bilang "mau ke ruang catatan nomor 2". Resepsionis membaca daftar ruangan dari atas, mengantar tamu ke ruangan pertama yang cocok, dan kalau gak ada yang cocok, tamu ditolak di meja depan. Di Express, daftar ruangan itu adalah route-route yang kamu tulis, dan ruangannya adalah function yang menjawab.
🧪 Tebakan cepat: request
GET /catatan/2?urut=judulmasuk ke routeapp.get("/catatan/:id", ...). Isireq.params.idapa: angka2, teks"2", atau"2?urut=judul"? Tebak dulu, jawabannya ada di bagian "Path parameter:req.params".
Route = method + path + handler
Proyek catatan-api kita sekarang punya dua route:
const express = require("express");
const app = express();
const catatan = [
{ id: 1, judul: "Belanja", isi: "beli beras 5 kg" },
{ id: 2, judul: "Belajar", isi: "bab Node.js" },
];
// Semua catatan, bisa disaring dengan ?cari=
app.get("/catatan", (req, res) => {
const { cari } = req.query;
if (!cari) return res.json(catatan);
const hasil = catatan.filter((c) => c.judul.toLowerCase().includes(cari.toLowerCase()));
res.json(hasil);
});
// Satu catatan berdasarkan id
app.get("/catatan/:id", (req, res) => {
const item = catatan.find((c) => c.id === Number(req.params.id));
if (!item) {
return res.status(404).json({ error: "Catatan tidak ditemukan" });
}
res.json(item);
});
app.listen(3000, () => {
console.log("Server jalan di http://localhost:3000");
});
app.get(path, handler)artinya: kalau datang request GET ke path ini, jalankan handler-nya. Ada jugaapp.post,app.put, danapp.deleteuntuk method lain.- Handler adalah function
(req, res) => { ... }.reqberisi semua tentang request yang masuk,resdipakai untuk menjawab. - Express mengecek route dari atas ke bawah. Yang pertama cocok method dan path-nya, itu yang menjawab. Route sesudahnya gak dicek lagi.
Path parameter: req.params
:id di path adalah path parameter: tempat kosong yang diisi dari URL. Satu route /catatan/:id melayani /catatan/1, /catatan/2, sampai /catatan/999.
| Request | Route yang cocok | req.params |
Jawaban |
|---|---|---|---|
GET /catatan/2 |
/catatan/:id |
{ id: "2" } |
{"id":2,"judul":"Belajar","isi":"bab Node.js"} |
GET /catatan/2?urut=judul |
/catatan/:id |
{ id: "2" } |
sama |
GET /catatan/9 |
/catatan/:id |
{ id: "9" } |
404 {"error":"Catatan tidak ditemukan"} |
Isi req.params selalu teks, karena URL memang teks. Bagian setelah ? gak ikut ke path, jadi gak ikut ke params. Jawabannya "2", teks. Itu jawaban tebakannya.
Karena teks, "2" === 2 hasilnya false. Makanya route di atas menulis Number(req.params.id) sebelum membandingkan dengan c.id yang berupa angka.
Query string: req.query
Bagian setelah ? adalah query string: pasangan kunci=nilai yang dipisah &. Express menaruhnya di req.query. curl "http://localhost:3000/catatan?cari=jar" mencetak [{"id":2,"judul":"Belajar","isi":"bab Node.js"}].
req.querydi sini{ cari: "jar" }. Dari dua judul, cuma "Belajar" yang mengandung "jar".- Query string gak menentukan route mana yang dipilih.
/catatan?cari=jartetap masuk ke route/catatan. - Pakai params untuk menunjuk satu data (
/catatan/2), query untuk mengatur daftar: cari, urutan, halaman.
Kalau gak ada route yang cocok
curl -i http://localhost:3000/halo dijawab HTTP/1.1 404 Not Found dengan halaman HTML kecil bawaan Express yang isinya <pre>Cannot GET /halo</pre>. Method juga dihitung: POST /catatan/2 dijawab Cannot POST /catatan/2, karena kita cuma punya route GET untuk path itu. Bedakan dengan 404 buatan kita sendiri, {"error":"Catatan tidak ditemukan"}: route-nya cocok, tapi datanya gak ada.
Dua hal yang dimaafkan Express: huruf besar kecil (/Catatan/2 tetap cocok) dan garis miring di akhir (/catatan/2/ tetap cocok).
Satu resource, lima route
Pola yang dipakai hampir semua API, namanya REST:
| Method | Path | Untuk |
|---|---|---|
| GET | /catatan |
daftar semua catatan |
| GET | /catatan/:id |
satu catatan |
| POST | /catatan |
bikin catatan baru |
| PUT | /catatan/:id |
ubah catatan |
| DELETE | /catatan/:id |
hapus catatan |
Path-nya kata benda (/catatan), aksinya ditentukan method. Tiga yang terakhir kita isi di pelajaran CRUD.
express.Router: route di file sendiri
Kalau route-nya makin banyak, pindahkan ke file sendiri dengan express.Router():
// routes/catatan.js
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => { /* daftar */ });
router.get("/:id", (req, res) => { /* satu catatan */ });
module.exports = router;
// app.js
const catatanRouter = require("./routes/catatan");
app.use("/catatan", catatanRouter);
app.use("/catatan", catatanRouter) menempelkan awalan /catatan ke semua route di router itu. Jadi router.get("/:id") melayani GET /catatan/:id, persis seperti sebelumnya.
📌 Express 5 beda dari tutorial lama
npm install express sekarang memasang Express 5. Banyak tutorial masih Express 4, dan dua pola path-nya bikin Express 5 berhenti waktu start:
| Express 4 | Express 5 | Kalau pola lama dipakai di Express 5 |
|---|---|---|
/catatan/:id? |
/catatan{/:id} |
PathError [TypeError]: Unexpected ? at index 12: /catatan/:id?; visit https://git.new/pathToRegexpError for info |
* |
/*splat |
PathError [TypeError]: Missing parameter name at index 1: *; visit https://git.new/pathToRegexpError for info |
Di latihan: route tanpa server
Latihannya gak menjalankan server. Fungsi findUser(id) memegang peran handler GET /users/:id: cari di array users dengan find, kembalikan user-nya, atau null kalau gak ada. find mengembalikan undefined kalau gak ketemu, jadi tulis return users.find((u) => u.id === id) || null;. Baris console.log di kode awal yang mencetak hasilnya:
GET /users/2 -> {"id":2,"name":"Siti"}
GET /users/99 -> User not found
⚠️ Jebakan yang sering ketemu
- Membandingkan params dengan angka.
c.id === req.params.idgak pernah cocok, karena2 === "2"itufalse. Hasilnya 404 untuk catatan yang ada. Ubah dulu denganNumber(req.params.id). - Urutan route. Kalau
app.get("/catatan/:id")ditulis sebelumapp.get("/catatan/terbaru"), request/catatan/terbaruditangkap duluan oleh:iddenganid="terbaru", dan jawabannya 404. Route yang spesifik taruh di atas. - Method salah. Route
app.getgak menjawab POST. HasilnyaCannot POST /catatan, walaupun path-nya sama persis. - Pola Express 4 di Express 5.
:id?dan*bikin server gagal start denganPathError.
TL;DR: Route = method + path + handler, dicek dari atas, yang pertama cocok yang menjawab. app.get("/catatan/:id", ...) mengisi req.params.id dari URL, selalu sebagai teks ("2", bukan 2), jadi ubah dengan Number() sebelum dibandingkan. Bagian setelah ? masuk ke req.query (?cari=jar jadi { cari: "jar" }) dan gak ikut menentukan route. Gak ada yang cocok: Express menjawab 404 Cannot GET /halo. REST: GET/POST/PUT/DELETE ke /catatan dan /catatan/:id. express.Router() memindahkan route ke file sendiri, dipasang dengan app.use("/catatan", router). Di Express 5, :id? jadi {/:id} dan * jadi /*splat.