Validasi Input & Arsitektur Berlapis

Tidak percaya pada input pengguna: validasi, pesan error yang jelas, dan memisahkan route, validasi, serta logika bisnis.

Part 20 dari 24 ± 40 menit Gratis

Aturan nomor satu: jangan percaya input

Semua yang datang dari luar — body, query, header, parameter URL — bisa salah, kosong, bertipe aneh, atau berniat jahat. Server yang baik memvalidasi sebelum memakai data. Tanpa validasi: data sampah masuk database, aplikasi crash karena undefined.toLowerCase(), dan celah keamanan terbuka.

Apa yang divalidasi?

  • Keberadaan: field wajib ada.
  • Tipe: string, angka, boolean — JSON tidak menjamin tipe.
  • Rentang & panjang: umur 17–100, nama 3–50 karakter.
  • Format: email, nomor telepon, tanggal.
  • Nilai yang diizinkan: status ∈ {draft, terbit}.

Fungsi validasi murni

Tulis validasi sebagai fungsi murni (input → daftar error, tanpa efek samping). Mudah diuji dan dipakai ulang:

function validasiPengguna(body) {
  const errors = {};
  if (typeof body.nama !== 'string' || body.nama.trim().length < 3) {
    errors.nama = 'nama minimal 3 karakter';
  }
  if (typeof body.email !== 'string' || !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(body.email)) {
    errors.email = 'email tidak valid';
  }
  if (!Number.isInteger(body.umur) || body.umur < 17 || body.umur > 100) {
    errors.umur = 'umur harus bilangan bulat 17–100';
  }
  return errors;       // objek kosong = valid
}

Respons validasi yang baik

Status 400 (atau 422) dengan pesan per field, agar antarmuka bisa menandai kolom yang salah:

{ "errors": { "nama": "nama minimal 3 karakter", "email": "email tidak valid" } }

Arsitektur berlapis

Memasukkan semuanya ke handler route membuat kode tak terbaca. Pisahkan berdasarkan tanggung jawab:

LapisanTugasContoh
RouteMemetakan URL ke controllerrouter.post('/', buat)
ControllerBaca request, panggil service, kirim response (HTTP saja)function buat(req, res)
ValidasiMemeriksa bentuk & nilai inputvalidasiPengguna(body)
ServiceLogika bisnis (tidak tahu HTTP)tambahPengguna(data)
Repository / modelAkses data (database)simpan(pengguna)
// service — tidak mengenal req/res
const pengguna = [];
function tambahPengguna(data) {
  if (pengguna.some((p) => p.email === data.email)) {
    const err = new Error('email sudah terdaftar'); err.status = 409; throw err;
  }
  const baru = { id: pengguna.length + 1, ...data };
  pengguna.push(baru);
  return baru;
}

// controller — hanya urusan HTTP
function buat(req, res) {
  const errors = validasiPengguna(req.body);
  if (Object.keys(errors).length) return res.status(400).json({ errors });
  res.status(201).json(tambahPengguna(req.body));
}

Keuntungannya: logika bisnis bisa dites tanpa menjalankan server; mengganti Express dengan framework lain atau array dengan database tidak memaksa menulis ulang semuanya.

Pustaka validasi

Untuk skema yang kompleks, pakai pustaka: Zod, Joi, Ajv (JSON Schema), atau express-validator. Prinsipnya sama dengan fungsi buatan sendiri di atas.

Sanitasi & keamanan

  • Jangan pernah menggabungkan input langsung ke query SQL (injeksi SQL) — pakai query berparameter.
  • Batasi ukuran body (express.json({ limit: '100kb' })).
  • Hanya ambil field yang kamu harapkan (jangan ...req.body mentah ke database — "mass assignment").

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X