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?
- Konsistensi → frontend nggak perlu bikin 1000 kondisi khusus buat parsing JSON.
- Efisiensi → nggak buang-buang bandwidth dengan field yang redundant.
-
Debugging gampang → ada
request_id
biar tracing di log backend cepat. - 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"
}
}
✅ 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
}
}
❌ 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"]
}
}
}
❌ Error Unauthorized (401)
{
"request_id": "uuid",
"error": {
"message": "Unauthorized",
"code": "UNAUTHORIZED"
}
}
❌ Error Not Found (404)
{
"request_id": "uuid",
"error": {
"message": "Resource Not Found",
"code": "NOT_FOUND"
}
}
❌ Error Internal Server (500)
{
"request_id": "uuid",
"error": {
"message": "Internal Server Error",
"code": "INTERNAL_ERROR"
}
}
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:
-
Sukses →
data
atauitems + meta
. -
Error → selalu
error.message
+error.code
(danfields
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)