Belajar Node.js - JSON API, CORS, dan Format Respons
Episode 10 of 23

Belajar Node.js - JSON API, CORS, dan Format Respons

Episode ini merancang API JSON yang konsisten: struktur payload yang seragam, pemilihan status code yang tepat, header CORS agar bisa diakses frontend, dan penanganan preflight OPTIONS. Kalian menguji semua header dengan curl.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

API yang berfungsi belum tentu API yang enak dipakai. Pengalaman mengonsumsi API ditentukan oleh tiga hal: format JSON yang konsisten, status code yang tepat, dan header CORS yang memungkinkan browser frontend mengaksesnya tanpa hambatan.

Episode 10 menyempurnakan API Express dari episode 9 menuju standar yang siap dikonsumsi frontend dan konsumen lain. Kalian akan merancang struktur respons yang seragam, memilih status code secara sadar, memasang CORS termasuk preflight OPTIONS, dan memverifikasi semuanya dengan curl.

Merancang Format Respons yang Konsisten

Envelope atau Data Polos

Ada dua gaya desain respons JSON yang umum: mengirim data polos langsung, atau membungkusnya dalam envelope:

JSRespons dengan envelope
app.get("/api/artikel", (req, res) => {
  res.json({
    status: "success",
    data: [{ id: 1, judul: "Belajar Node.js" }],
  });
});

Envelope memberi tempat konsisten untuk metadata seperti paginasi dan pesan error. Untuk project kecil, data polos juga sah. Yang terpenting: pilih satu gaya dan konsisten di seluruh endpoint — jangan campur data polos dan envelope dalam satu API.

Konsistensi adalah Kontrak

Konsistensi menjadi kontrak antara API dan konsumennya. Jika satu endpoint mengembalikan envelope dan endpoint lain mengembalikan array polos, konsumen harus menebak format per endpoint — sumber bug yang tak perlu. Tuliskan konvensi ini dalam dokumentasi API dan patuhi di semua route.

Status Code yang Tepat

Memetakan Hasil ke Kode HTTP

Status code adalah bahasa universal antara server dan klien. Pastikan setiap endpoint mengembalikan kode yang menggambarkan hasil sebenarnya:

JSStatus code yang tepat
app.post("/api/artikel", (req, res) => {
  const artikel = simpanArtikel(req.body);
  res.status(201).json({ status: "success", data: artikel });
});
 
app.get("/api/artikel/:id", (req, res) => {
  const artikel = cariArtikel(req.params.id);
  if (!artikel) {
    res.status(404).json({ status: "error", error: "Artikel tidak ditemukan" });
    return;
  }
  res.json({ status: "success", data: artikel });
});

Perhatikan res.status(201).json(...) untuk resource yang baru dibuat dan res.status(404).json(...) untuk data yang tidak ditemukan. Pola yang sama berlaku untuk 400 (input tidak valid), 401 (belum login), dan 403 (tidak punya izin) yang akan kita bahas di episode 11.

CORS dan Preflight Request

Mengapa CORS Diperlukan

Browser menerapkan Same-Origin Policy: JavaScript dari http://localhost:5173 tidak bisa membaca respons dari http://localhost:3000 tanpa izin. CORS (Cross-Origin Resource Sharing) adalah mekanisme izin itu, dikendalikan lewat header respons.

Untuk memilih origin yang diizinkan, tambahkan header Access-Control-Allow-Origin:

JSMiddleware CORS
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "http://localhost:5173");
  res.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
  res.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization");
  if (req.method === "OPTIONS") {
    res.sendStatus(204);
    return;
  }
  next();
});

Middleware di atas mengizinkan origin frontend tertentu. Nilai "*" mengizinkan semua origin — praktis untuk API publik, tapi hindari untuk API dengan autentikasi. Header Allow-Headers wajib memuat Content-Type dan Authorization agar frontend bisa mengirim JSON dan token.

Preflight OPTIONS

Untuk request non-sederhana — seperti POST dengan Content-Type: application/json atau request dengan header Authorization — browser mengirim preflight berupa request OPTIONS terlebih dahulu, lalu menunggu izin sebelum request asli. Jika preflight tidak dijawab dengan CORS yang benar, request asli dibatalkan. Blok if (req.method === "OPTIONS") di atas memastikan preflight dijawab dengan cepat tanpa diproses sebagai request biasa.

Memverifikasi dengan curl

Menguji Header dari Terminal

curl -i menampilkan seluruh header respons. Uji CORS kalian dengan header Origin:

Uji CORS dengan curl
curl -i -H "Origin: http://localhost:5173" http://localhost:3000/api/artikel
curl -i -X OPTIONS http://localhost:3000/api/artikel \
  -H "Origin: http://localhost:5173" \
  -H "Access-Control-Request-Method: POST"

curl -i -H "Origin: http://localhost:5173" http://localhost:3000/api/artikel harus menampilkan header Access-Control-Allow-Origin pada respons. Baris kedua mensimulasikan preflight OPTIONS yang harus dibalas dengan status 204 dan header CORS yang lengkap. Jika keduanya benar, frontend kalian bisa mengakses API tanpa masalah.

Penutup

Inti yang harus dibawa pulang:

  • Pilih satu gaya respons JSON dan konsisten di semua endpoint.
  • res.status(201) untuk resource baru dan 404 untuk data hilang.
  • Browser menerapkan Same-Origin Policy; CORS memberi izin lewat header.
  • Header Allow-Headers wajib memuat Content-Type dan Authorization.
  • Preflight OPTIONS dijawab dengan status 204 dan header CORS.
  • Verifikasi header CORS dengan curl -i dan header Origin.

Di episode 11 selanjutnya kita akan membahas autentikasi dan otorisasi dasar — menyimpan password dengan hash yang aman, menerbitkan token JWT, middleware untuk memverifikasi token, dan kontrol akses berbasis peran. Setelah ini, API kalian punya lapisan keamanan pertama.

Belajar Node.js - JSON API, CORS, dan Format Respons | Belajar Node.js