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_idbiar 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 →
datakalau sukses,errorkalau gagal. -
Selalu ada
request_idbuat 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 →
dataatauitems + meta. -
Error → selalu
error.message+error.code(danfieldskalau 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)