DEV Community

Nandan Ramdani
Nandan Ramdani

Posted on

Best Practice API Response JSON Ringkas, Konsisten, dan Mudah Ditelusuri

Kalau kita ngomongin soal bikin API, biasanya fokusnya ada di endpoint dan fitur. Tapi sering banget bagian respons API disepelekan. Padahal, kalau format responsnya berantakan, ujung-ujungnya frontend jadi ribet, debugging jadi susah, dan bandwidth kepake lebih banyak dari seharusnya.

Di blog ini, kita bakal bahas gimana sih format API response yang ideal: ringkas, konsisten, gampang ditelusuri, dan ramah untuk frontend.


Kenapa Format Respons API Penting?

  1. Konsistensi → frontend nggak perlu bikin 1000 kondisi khusus buat parsing JSON.
  2. Efisiensi → nggak buang-buang bandwidth dengan field yang redundant.
  3. Debugging gampang → ada request_id biar tracing di log backend cepat.
  4. Multibahasa oke → error code standar bisa ditranslate frontend sesuai bahasa user.

Intinya: bikin hidup developer frontend lebih tenang, dan developer backend lebih gampang ngelacak error. Win-win!


Prinsip Dasar Format Respons

Ada beberapa prinsip yang bisa kita pegang:

  • HTTP status code dipakai buat status utama (200, 400, 401, 404, 500, dst).
  • Body respons fokus ke isi → data kalau sukses, error kalau gagal.
  • Selalu ada request_id buat tracing.
  • Error pakai kode standar → frontend yang nentuin pesan human-friendly.

Contoh Format Respons Konsisten

✅ Respons Sukses – Single Resource

{
  "request_id": "uuid",
  "data": {
    "id": 123,
    "name": "Nandan",
    "email": "nandan@example.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

✅ Respons Sukses – List + Pagination

{
  "request_id": "uuid",
  "items": [
    { "id": 1, "title": "First Item" },
    { "id": 2, "title": "Second Item" }
  ],
  "meta": {
    "page": 1,
    "per_page": 10,
    "total": 25
  }
}
Enter fullscreen mode Exit fullscreen mode

❌ Error Validasi (400/422)

{
  "request_id": "uuid",
  "error": {
    "message": "Payload Validation Failed",
    "code": "VALIDATION_ERROR",
    "fields": {
      "email": ["REQUIRED", "INVALID_FORMAT", "UNIQUE"],
      "password": ["REQUIRED", "MIN_LENGTH"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

❌ Error Unauthorized (401)

{
  "request_id": "uuid",
  "error": {
    "message": "Unauthorized",
    "code": "UNAUTHORIZED"
  }
}
Enter fullscreen mode Exit fullscreen mode

❌ Error Not Found (404)

{
  "request_id": "uuid",
  "error": {
    "message": "Resource Not Found",
    "code": "NOT_FOUND"
  }
}
Enter fullscreen mode Exit fullscreen mode

❌ Error Internal Server (500)

{
  "request_id": "uuid",
  "error": {
    "message": "Internal Server Error",
    "code": "INTERNAL_ERROR"
  }
}
Enter fullscreen mode Exit fullscreen mode

Daftar Kode Error Standar

Supaya konsisten, backend harus pakai kode error yang jelas. Frontend cukup mapping kode ini ke pesan sesuai bahasa.

🔹 Validasi

  • REQUIRED → field kosong padahal wajib
  • INVALID_TYPE → tipe data salah
  • INVALID_FORMAT → format salah (contoh: email nggak valid)
  • MIN_LENGTH / MAX_LENGTH → panjang string nggak sesuai
  • MIN_VALUE / MAX_VALUE → angka nggak sesuai batas
  • UNIQUE → data sudah ada (contoh: email sudah terpakai)
  • ENUM_VALUE → pilihan tidak valid
  • MISMATCH → konfirmasi nggak cocok (contoh: password & confirm_password)

🔹 Auth & Security

  • UNAUTHORIZED → belum login / token nggak ada
  • INVALID_TOKEN → token expired atau salah
  • FORBIDDEN_ACTION → user nggak punya izin
  • ACCOUNT_LOCKED → akun terkunci
  • TOO_MANY_REQUESTS → rate limit tercapai

🔹 Server

  • INTERNAL_ERROR → error tak terduga
  • SERVICE_UNAVAILABLE → dependency down
  • TIMEOUT → request timeout
  • CONFLICT → resource conflict

Kenapa Nggak Perlu Field Tambahan Kayak resource?

Sederhana aja: kalau kita request ke /users/123 dan responsnya 404 NOT_FOUND, udah jelas resource yang dimaksud adalah user.
Menambahkan "resource": "user" di body malah bikin inkonsistensi karena nggak semua error butuh field itu. Jadi mendingan minimalis dan konsisten.


Kesimpulan

Format respons API yang ideal itu:

  • Suksesdata atau items + meta.
  • Error → selalu error.message + error.code (dan fields kalau validasi).
  • Selalu ada request_id.
  • Frontend yang translate error code, bukan backend.

Dengan format ini:

  • Backend lebih ringan dan hemat bandwidth.
  • Frontend lebih fleksibel dan bisa multi-bahasa.
  • Debugging lebih gampang karena ada request_id.

👉 Jadi, sebelum mikirin microservices atau scaling yang ribet, pastikan dulu API kamu punya respons yang konsisten, rapi, dan developer-friendly. Percaya deh, ini bakal menghemat banyak waktu dan tenaga tim di masa depan.

Top comments (0)