Banyak masalah dalam aplikasi web bukan muncul karena fitur yang terlalu rumit, melainkan karena frontend dan backend tidak memiliki kesepakatan yang jelas. Backend mengirim respons berbeda-beda, frontend menebak arti setiap status, lalu error kecil berubah menjadi debugging berjam-jam.
API atau Application Programming Interface adalah jalur komunikasi antarbagian aplikasi. Dalam website modern, API biasanya mengirim dan menerima data melalui HTTP dalam format seperti JSON. Namun, API yang baik tidak cukup hanya bisa mengembalikan data. Ia juga harus memiliki aturan yang mudah dipahami, konsisten, dan bisa membantu pengembang menemukan masalah.
API perlu memiliki “kontrak” yang jelas
Bayangkan API seperti loket layanan. Pengguna perlu tahu dokumen apa yang harus dibawa, format permintaan yang diterima, dan bentuk jawaban yang akan diberikan. Jika setiap petugas memberikan aturan berbeda, prosesnya akan membingungkan.
Kontrak API adalah kesepakatan tentang beberapa hal penting, antara lain:
- Endpoint yang tersedia, misalnya
GET /api/products. - Parameter atau data yang wajib dikirim.
- Format respons ketika permintaan berhasil.
- Status HTTP yang digunakan.
- Format pesan ketika terjadi error.
- Aturan autentikasi dan batasan akses.
Kontrak ini tidak harus langsung ditulis dalam dokumen yang panjang. Bahkan contoh request dan response sederhana di dokumentasi proyek sudah jauh lebih baik daripada tidak ada aturan sama sekali.
Gunakan status HTTP sesuai maknanya
Status HTTP membantu client memahami hasil permintaan tanpa harus membaca semua isi respons. Masalahnya, sebagian API memakai status 200 OK untuk hampir semua kondisi, termasuk ketika data tidak ditemukan atau validasi gagal.
Pola yang lebih mudah dirawat adalah menggunakan status sesuai konteks:
200 OKuntuk permintaan berhasil dan menghasilkan respons.201 Createdketika resource baru berhasil dibuat.204 No Contentketika operasi berhasil tetapi tidak ada isi yang perlu dikirim.400 Bad Requestketika format permintaan tidak valid.401 Unauthorizedketika pengguna belum terautentikasi.403 Forbiddenketika pengguna sudah dikenali tetapi tidak memiliki izin.404 Not Foundketika resource yang diminta tidak tersedia.422 Unprocessable Contentketika format data benar, tetapi isinya gagal validasi.500 Internal Server Erroruntuk kegagalan tak terduga di sisi server.
Status HTTP bukan pengganti pesan error, tetapi menjadi sinyal awal yang sangat berguna. Frontend dapat membedakan kapan harus menampilkan form validasi, meminta pengguna login kembali, atau menampilkan pesan gangguan server.
Samakan bentuk respons sukses dan error
Respons yang konsisten mengurangi logika khusus di sisi frontend. Misalnya, respons sukses selalu memiliki objek data, sedangkan error selalu memiliki error dengan kode dan pesan yang jelas.
{
"data": {
"id": 42,
"name": "Keyboard Wireless"
},
"meta": {}
}Untuk error, gunakan struktur yang dapat diproses mesin sekaligus masih mudah dibaca manusia:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Data yang dikirim belum valid.",
"details": {
"email": "Format email tidak benar."
},
"request_id": "req_8f21ab"
}
}Field code sebaiknya stabil dan tidak bergantung pada kalimat yang bisa berubah. Frontend dapat memakai VALIDATION_ERROR untuk menentukan perilaku, sementara message ditampilkan kepada pengguna. Jika error terjadi di produksi, request_id membantu tim mencari kejadian yang sama di log server.
Bedakan pesan untuk pengguna dan detail untuk pengembang
Pesan error yang terlalu teknis tidak membantu pengguna. Sebaliknya, pesan yang terlalu umum menyulitkan pengembang saat mencari penyebabnya.
Contohnya, pengguna tidak perlu melihat pesan seperti SQLSTATE[23000]: Integrity constraint violation. Pesan tersebut bisa diterjemahkan menjadi “Kode produk sudah digunakan.” Detail teknisnya tetap dicatat di log server, bukan dikirim mentah ke browser.
Hindari mengirim:
- Informasi koneksi database.
- Path file di server.
- Query SQL lengkap.
- Stack trace pada lingkungan produksi.
- Token, password, atau data pribadi.
Ini bukan hanya soal kenyamanan. Detail internal yang bocor dapat membantu pihak tidak berwenang memahami struktur aplikasi dan mencari celah keamanan.
Validasi harus dilakukan di lebih dari satu tempat
Frontend boleh melakukan validasi untuk memberi umpan balik cepat, tetapi backend tetap harus memvalidasi ulang. Data dari browser tidak boleh dianggap tepercaya karena request dapat dibuat menggunakan alat lain, bukan hanya melalui tampilan website.
Misalnya, frontend memeriksa agar harga tidak boleh negatif. Backend tetap harus melakukan pemeriksaan yang sama sebelum menyimpan data ke database. Untuk field penting, validasi juga sebaiknya diperkuat dengan aturan database, seperti unique constraint atau foreign key.
Pendekatan berlapis ini memang menambah sedikit pekerjaan, tetapi mencegah data rusak ketika API dipanggil oleh aplikasi mobile, script otomatis, atau integrasi pihak ketiga.
Tambahkan request ID dan log yang terarah
Ketika pengguna melaporkan “tadi error”, tim biasanya kekurangan informasi. Waktu kejadian bisa tidak jelas, endpoint yang dipanggil belum diketahui, dan pesan error mungkin sudah hilang.
Request ID membantu menghubungkan respons API dengan catatan di server. Setiap request dapat diberi ID unik, lalu ID tersebut dikirim kembali dalam respons dan disimpan di log bersama informasi penting seperti:
- Waktu request.
- Endpoint dan metode HTTP.
- Status respons.
- Durasi proses.
- ID pengguna jika tersedia dan aman dicatat.
- Ringkasan error tanpa data sensitif.
Log yang baik tidak berarti menyimpan semua hal. Data pribadi dan kredensial harus disamarkan atau tidak dicatat sama sekali.
Uji API dengan skenario nyata
Pengujian API jangan berhenti pada satu contoh sukses. Minimal, siapkan skenario untuk data kosong, parameter hilang, autentikasi gagal, akses tanpa izin, resource tidak ditemukan, input terlalu panjang, dan kegagalan layanan eksternal.
Contoh checklist sederhana:
- Apakah status HTTP sesuai dengan kondisi sebenarnya?
- Apakah bentuk respons tetap konsisten?
- Apakah error bisa dipahami frontend?
- Apakah data sensitif tidak ikut terkirim?
- Apakah request ID muncul di respons dan log?
- Apakah API tetap aman ketika dipanggil tanpa melalui UI?
Apa artinya bagi kita?
API yang rapi bukan berarti semua endpoint harus sempurna sejak hari pertama. Yang lebih penting adalah memiliki pola yang dapat diulang. Mulailah dari satu format respons, daftar status HTTP yang disepakati, validasi backend, dan pesan error yang tidak membocorkan detail internal.
Setelah itu, dokumentasikan contoh request dan response. Jika tim bertambah atau aplikasi mulai terhubung dengan layanan lain, kontrak ini akan menghemat waktu komunikasi dan mengurangi risiko perubahan kecil merusak banyak bagian.
Pada akhirnya, kualitas API terlihat bukan hanya ketika semuanya berjalan lancar, tetapi juga ketika terjadi kesalahan. API yang baik memberi tahu apa yang terjadi, tidak membocorkan hal yang seharusnya rahasia, dan membantu orang yang tepat memperbaiki masalah dengan cepat.
– Rio Yotto @rioyotto
