Di balik setiap aplikasi web yang terasa “ajaib” saat berpindah halaman, mengirim formulir, atau menampilkan data secara dinamis, ada satu konsep yang bekerja tanpa henti: routing. Di dunia Node.js, Express.js menjadi salah satu kerangka kerja favorit untuk mengatur alur lalu lintas permintaan (request) dan respons (response) ini. Namun, sebelum melangkah jauh ke fitur-fitur canggihnya, ada empat “pemeran utama” yang perlu benar-benar dipahami: GET, POST, PUT, dan DELETE.
Keempat metode HTTP ini adalah fondasi dari komunikasi antara client dan server. Mereka menentukan apa yang ingin dilakukan oleh sebuah permintaan: mengambil data, mengirim data baru, memperbarui, atau menghapusnya. Tanpa pemahaman yang jelas tentang cara kerja masing-masing, routing di Express.js bisa terasa membingungkan, atau bahkan berujung pada bug yang sulit dilacak.
Artikel ini akan membahas konsep routing di Express.js dengan fokus pada empat metode tersebut. Mulai dari cara mendefinisikan rute dasar, mengelola parameter, hingga memahami peran masing-masing metode dalam merancang API yang rapi dan mudah dirawat. Dengan memahaminya, Anda dapat membangun struktur aplikasi yang lebih teratur, konsisten, dan siap dikembangkan lebih lanjut.
Membedah Dasar Routing Express js Memahami Peran Method GET POST PUT DELETE dalam REST API
Di dunia Express.js, setiap method HTTP sebenarnya punya “kepribadian” dan tugas masing-masing. GET dipakai untuk mengambil data tanpa mengubah apa pun di server, sementara POST cocok saat kamu ingin mengirim data baru, misalnya membuat user atau menyimpan komentar. Lalu ada PUT yang biasanya dipakai untuk memperbarui data secara keseluruhan, dan DELETE yang, sesuai namanya, bertugas menghapus data. Kombinasi empat method ini membentuk pola dasar REST API yang rapi dan mudah dipahami, karena tiap aksi terhadap resource (data) punya jalur dan aturan sendiri. Di Express.js, kamu cukup memetakan URL (route) ke fungsi yang sesuai dengan method yang dipakai klien.
- GET – membaca data tanpa mengubah state di server.
- POST – menambah resource baru, biasanya dengan body request.
- PUT – mengganti atau memperbarui resource yang sudah ada.
- DELETE – menghapus resource berdasarkan identifier tertentu.
| Method | Contoh Endpoint | Tujuan Singkat |
|---|---|---|
| GET | /api/users |
Ambil daftar user |
| POST | /api/users |
Tambah user baru |
| PUT | /api/users/:id |
Update data user |
| DELETE | /api/users/:id |
Hapus user |
Menulis routing di Express.js sebenarnya cukup santai, mirip ngobrol: kamu bilang ke server, “kalau ada request dengan method tertentu ke URL ini, jalankan fungsi ini ya.” Misalnya, buat mengambil semua user, kamu bisa menulis route GET, lalu menyiapkan callback yang mengembalikan data JSON. Untuk menambahkan user baru, kamu memakai route POST dan membaca data dari req.body. Dengan memisahkan logika berdasarkan method, kode jadi lebih bersih dan mudah di-maintain, karena kamu tahu persis endpoint mana yang hanya boleh baca data dan mana yang berhak memodifikasinya.
const express = require('express');
const app = express();
app.use(express.json());
// GET - baca data
app.get('/api/users', (req, res) => {
res.json([{ id: 1, name: 'Ayu' }]);
});
// POST - tambah data
app.post('/api/users', (req, res) => {
const newUser = req.body;
res.status(201).json(newUser);
});
// PUT - update data
app.put('/api/users/:id', (req, res) => {
const { id } = req.params;
const updatedUser = { id, ...req.body };
res.json(updatedUser);
});
// DELETE - hapus data
app.delete('/api/users/:id', (req, res) => {
res.status(204).send();
});
Merancang Struktur Route yang Rapi dan Skalabel dari Single File hingga Modular Router
Di proyek kecil, menaruh semua route di satu file app.js mungkin terasa praktis. Tapi begitu jumlah endpoint mulai banyak, file itu bisa berubah jadi “gorengan campur aduk”. Supaya tetap rapi, biasakan sejak awal memisahkan tanggung jawab: file utama cukup fokus pada konfigurasi global, sedangkan detail endpoint pindah ke modul terpisah. Pola sederhananya biasanya seperti ini:
- File utama: inisialisasi Express, middleware global, koneksi database, mount router.
- Router per fitur: misalnya
routes/users.js,routes/posts.js, masing-masing pegang route GET, POST, PUT, DELETE untuk domain itu saja. - Controller: fungsi-fungsi handler dipisah lagi supaya file router tetap tipis dan gampang dibaca.
| Level | Fokus | Contoh File |
|---|---|---|
| Aplikasi | Konfigurasi utama | app.js |
| Router | Definisi endpoint | routes/users.js |
| Controller | Logika bisnis | controllers/userController.js |
Begitu pola ini diterapkan, menambah route baru terasa jauh lebih santai. Kamu cukup bikin file router baru, lalu mount di aplikasi utama tanpa menyentuh bagian lain yang sudah stabil. Kira-kira alurnya seperti ini:
- Buat router modular dengan express.Router().
- Taruh semua endpoint terkait resource tertentu di sana (GET, POST, PUT, DELETE).
- Impor router itu di file utama dan
app.use()ke prefix path tertentu, misalnya/api/users.
“`js
// app.js
const express = require(‘express’);
const app = express();
const userRouter = require(‘./routes/users’);
app.use(express.json());
app.use(‘/api/users’, userRouter);
app.listen(3000);
“`
“`js
// routes/users.js
const express = require(‘express’);
const router = express.Router();
// GET /api/users
router.get(‘/’, (req, res) => {
res.json([{ id: 1, name: ‘Alice’ }]);
});
// POST /api/users
router.post(‘/’, (req, res) => {
res.status(201).json({ message: ‘User created’ });
});
module.exports = router;
“`
Mengelola Data dengan Aman Validasi Input dan Penanganan Error di Setiap Endpoint
Di setiap route, anggap semua data dari klien itu “meragukan” sampai terbukti aman. Biasakan memfilter dan memvalidasi input sebelum menyentuh logika utama atau database. Kamu bisa pakai library seperti Joi, Yup, atau express-validator untuk memeriksa tipe data, panjang teks, format email, dan sebagainya. Prinsipnya: jangan pernah percaya pada body POST, query GET, atau parameter PUT/DELETE tanpa dicek. Kalau data nggak lolos validasi, langsung kembalikan respons yang rapi, misalnya status 400 Bad Request dengan pesan singkat tapi jelas. Dengan begitu, endpoint tetap bersih, mudah dirawat, dan nggak penuh kondisi acak-acakan.
- Validasi awal: cek semua field penting sebelum menjalankan logika bisnis.
- Sanitasi input: hapus karakter berbahaya, trimming, dan normalisasi data.
- Penanganan error terpusat: gunakan middleware khusus untuk menangani error secara konsisten.
- Respon terstruktur: selalu kirim format JSON yang konsisten untuk keberhasilan maupun kegagalan.
| Jenis Error | Status HTTP | Contoh Pesan |
|---|---|---|
| Validasi Gagal | 400 | Data tidak valid |
| Data Tidak Ditemukan | 404 | Resource tidak ditemukan |
| Error Server | 500 | Terjadi kesalahan pada server |
Di Express.js, cara yang enak adalah memisahkan logika error dari route utama. Setiap kali ada sesuatu yang salah – entah dari database, service eksternal, atau bug di kode – lempar saja error ke middleware khusus. Di sana kamu bisa mengatur: status code apa yang dikirim, bentuk JSON seperti apa, dan apakah detail error teknis perlu ditampilkan (biasanya jangan di environment produksi). Pendekatan ini bikin setiap GET, POST, PUT, dan DELETE punya pola yang sama: validasi dulu, jalankan proses, lalu tangani error di satu tempat yang konsisten. Hasil akhirnya, API lebih rapi, mudah di-debug, dan jauh lebih aman untuk dipakai jangka panjang.
Praktik Terbaik dalam Membangun API Express js Otentikasi Logging dan Pengujian Route
Supaya API yang kamu bangun tidak mudah “jebol” dan gampang dilacak jika ada masalah, biasakan menata otentikasi, logging, dan pengujian langsung di level route. Misalnya, buat middleware auth terpisah lalu pasang hanya di route yang sensitif, bukan semuanya diborong jadi satu. Logging juga sebaiknya tidak asal console.log, tapi diarahkan ke sistem yang rapi dan konsisten, pakai metadata seperti method, path, status, sampai waktu eksekusi. Struktur folder yang bersih akan sangat membantu, misalnya memisahkan route publik dan privat, lalu menambahkan lapisan validasi payload sebelum request masuk ke handler utama.
- Gunakan middleware otentikasi per grup route (misalnya
/api/admindan/api/user). - Catat log dengan level berbeda: info, warn, error.
- Tulis pengujian otomatis untuk setiap method: GET, POST, PUT, DELETE.
- Simulasikan skenario error, bukan hanya skenario sukses.
- Jangan lupa sanitasi input sebelum menyentuh database.
| Aspek | Praktik Baik | Contoh Singkat |
|---|---|---|
| Otentikasi | Token di header, bukan di query | Authorization: Bearer |
| Logging | Middleware terpusat | Log method, path, status |
| Pengujian | Test per route & method | Gunakan library HTTP testing |
// contoh setup middleware otentikasi & logging di Express
const express = require('express');
const app = express();
function logger(req, res, next) {
const start = Date.now();
res.on('finish', () => {
const time = Date.now() - start;
console.log(`[${req.method}] ${req.originalUrl} - ${res.statusCode} (${time}ms)`);
});
next();
}
function auth(req, res, next) {
const header = req.headers.authorization;
if (!header || !header.startsWith('Bearer ')) {
return res.status(401).json({ message: 'Token tidak valid atau tidak ada' });
}
// di sini biasanya token diverifikasi
next();
}
app.use(logger);
app.get('/api/profile', auth, (req, res) => {
res.json({ name: 'User Contoh', role: 'member' });
});
// contoh pengujian route dengan supertest
const request = require('supertest');
const app = require('../app'); // asumsi file utama Express
describe('Route GET /api/profile', () => {
it('mengembalikan 401 jika tanpa token', async () => {
const res = await request(app).get('/api/profile');
expect(res.statusCode).toBe(401);
});
it('mengembalikan 200 jika token benar', async () => {
const res = await request(app)
.get('/api/profile')
.set('Authorization', 'Bearer token-palsu-tapi-format-benar');
expect(res.statusCode).toBe(200);
});
});
Closing Remarks
Pada akhirnya, memahami routing di Express.js-mulai dari GET yang ramah membaca data, POST yang rajin menerima kiriman, hingga PUT dan DELETE yang tegas mengatur pembaruan dan penghapusan-adalah fondasi penting dalam membangun API yang rapi dan terstruktur.
Setiap rute yang Anda tulis bukan sekadar baris kode, tetapi juga “jalan” yang menghubungkan permintaan pengguna dengan logika aplikasi yang Anda rancang. Semakin jelas dan konsisten cara Anda mengatur rute, semakin mudah pula aplikasi dikembangkan, diuji, dan dipelihara dalam jangka panjang.
Setelah memahami dasar-dasarnya, langkah selanjutnya bergantung pada Anda: bereksperimen dengan middleware, mengelompokkan rute dengan Router, menambahkan validasi, hingga mengintegrasikan dengan database. Dari sini, Express.js memberi ruang yang cukup luas untuk Anda membangun alur perjalanan data sesuai kebutuhan aplikasi-satu rute pada satu waktu.

