💡 Key Takeaways
- Authentication and Authorization: The Foundation Layer
- Request Validation: Input Boundary Testing
- Response Validation: Ensuring Data Integrity
- Error Handling: The Difference Between Good and Great APIs
Tiga tahun yang lalu, saya menyaksikan sebuah API produksi gagal secara spektakuler pada jam 2 pagi karena tidak ada yang menguji apa yang terjadi ketika Anda mengirimkan field tanggal yang diformat sebagai "32/13/2021." Cascade-nya sangat indah dengan cara yang paling buruk: 47.000 transaksi gagal, pelanggan marah membanjiri saluran dukungan, dan seorang CEO yang menginginkan jawaban yang saya tidak miliki. Malam itu mengubah cara saya mendekati pengujian API selamanya.
💡 Poin Penting
- Autentikasi dan Otorisasi: Lapisan Dasar
- Validasi Permintaan: Pengujian Batas Input
- Validasi Respons: Memastikan Integritas Data
- Penanganan Kesalahan: Perbedaan Antara API Baik dan Hebat
Saya Sarah Chen, dan saya telah menjadi insinyur otomatisasi QA selama delapan tahun, lima tahun terakhir fokus secara eksklusif pada pengujian API untuk platform fintech dan kesehatan. Saya telah menguji semuanya dari titik akhir CRUD yang sederhana hingga API pemrosesan pembayaran yang kompleks yang menangani jutaan dolar setiap hari. Apa yang saya pelajari adalah ini: sebagian besar kegagalan API bukanlah kasus tepi yang eksotis—mereka adalah masalah yang dapat diprediksi yang akan tertangkap oleh checklist sistematis.
Checklist yang saya bagikan hari ini adalah yang saya gunakan untuk setiap titik akhir yang saya uji. Ini telah menyelamatkan tim saya dari setidaknya selusin insiden produksi hanya dalam setahun terakhir, dan cukup komprehensif sehingga insinyur junior dapat mengikutinya dan cukup detail sehingga menangkap masalah yang terlewat oleh pengembang senior. Ini bukan teori—ini adalah proses yang telah teruji di lapangan yang disempurnakan melalui ratusan implementasi API.
Autentikasi dan Otorisasi: Lapisan Dasar
Sebelum saya menguji apa pun, saya memverifikasi perimeter keamanan. Ini bukan hanya tentang memeriksa apakah autentikasi berfungsi—ini tentang secara sistematis menyelidiki setiap skenario autentikasi dan batas otorisasi. Saya telah melihat terlalu banyak API yang berfungsi dengan baik dengan kredensial yang valid namun gagal secara katastrofal atau bocor data ketika kredensial hilang, salah format, atau milik pengguna yang salah.
Pertama, saya menguji tanpa token autentikasi sama sekali. Titik akhir harus mengembalikan status 401 Tidak Terotorisasi, bukan 500 Kesalahan Server Internal, dan pasti bukan data aktual. Saya pernah menemui API produksi yang mengembalikan catatan pengguna lengkap ketika tidak ada token autentikasi yang diberikan karena pengembang menganggap middleware autentikasi akan selalu berjalan. Itu tidak.
Selanjutnya, saya menguji dengan token yang kedaluwarsa. Ini menangkap jumlah masalah yang mengejutkan karena logika kedaluwarsa token sering berada di bagian kode yang berbeda dari autentikasi awal. Respons harus berupa 401 yang jelas dengan pesan yang menunjukkan token telah kedaluwarsa, bukan "tidak terotorisasi" yang umum yang membuat klien menebak apakah harus menyegarkan atau autentikasi ulang.
Kemudian saya menguji dengan token yang salah format—string acak, token dengan karakter yang dihapus, token dari sistem lain. API harus menangani ini dengan baik tanpa mengekspos jejak tumpukan atau detail kesalahan internal. Suatu ketika saya menemukan API yang akan menghancurkan seluruh layanan ketika diberikan token yang mengandung karakter Unicode tertentu karena perpustakaan parsing JWT tidak menangani pengkodean dengan baik.
Pengujian otorisasi adalah tempat segalanya menjadi menarik. Saya menguji dengan token yang valid milik pengguna yang seharusnya tidak memiliki akses ke sumber daya. Untuk titik akhir GET /users/123, saya akan mengautentikasi sebagai pengguna 456 dan mencoba mengakses data 123. Respons harus 403 Dilarang, bukan 404 Tidak Ditemukan (yang membocorkan informasi tentang keberadaan sumber daya) dan pasti bukan 200 dengan data.
Saya juga menguji kontrol akses berbasis peran secara sistematis. Jika API Anda memiliki peran admin, manajer, dan pengguna, saya menguji setiap titik akhir dengan setiap peran. Saya mempertahankan spreadsheet matriks: baris adalah titik akhir, kolom adalah peran, sel berisi kode status yang diharapkan. Ini menangkap bug izin sebelum mereka mencapai produksi, di mana mereka menjadi kerentanan keamanan.
Validasi Permintaan: Pengujian Batas Input
Validasi input adalah di mana sebagian besar API menunjukkan kualitas sebenarnya. API yang dirancang dengan baik memvalidasi setiap field input secara menyeluruh dan mengembalikan pesan kesalahan yang jelas dan dapat ditindaklanjuti. Yang dirancang buruk baik menerima data sampah atau mogok secara misterius.
"Sebagian besar kegagalan API bukan kasus tepi yang eksotis—mereka adalah masalah yang dapat diprediksi yang akan tertangkap oleh checklist sistematis."
Saya mulai dengan pengujian field yang diperlukan. Untuk setiap field yang diperlukan, saya mengirimkan permintaan tanpa itu. API harus mengembalikan 400 Permintaan Buruk dengan pesan yang secara jelas mengidentifikasi field mana yang hilang. Saya telah melihat API yang mengembalikan "kesalahan validasi" tanpa menentukan apa yang gagal, memaksa pengembang menebak field mana dari 15 yang menyebabkan masalah.
Selanjutnya saya menguji validasi tipe data. Jika sebuah field mengharapkan bilangan bulat, saya mengirimkan string, float, boolean, null, array, dan objek. Setiap satu harus mengembalikan 400 dengan pesan jelas seperti "usia harus berupa bilangan bulat" bukan "format permintaan tidak valid." Suatu ketika, saya menguji sebuah API e-commerce di mana mengirimkan string untuk kuantitas menyebabkan sistem membuat pesanan untuk nol item, yang merusak seluruh jalur pemenuhan.
Validasi panjang string sangat penting dan sering diabaikan. Saya menguji dengan string kosong, karakter tunggal, string pada panjang maksimum, string satu karakter di atas maksimum, dan string yang sangat panjang (10.000+ karakter). Saya pernah menghancurkan basis data produksi dengan mengirimkan string berukuran megabyte ke field yang tidak divalidasi dengan baik, menyebabkan kehabisan memori.
Untuk field numerik, saya menguji nilai batas secara sistematis: nol, angka negatif, desimal ketika bilangan bulat diharapkan, angka yang lebih besar dari nilai bilangan bulat maksimum, dan nilai khusus seperti Infinity atau NaN. Suatu ketika saya menguji API pembayaran yang menerima jumlah pembayaran negatif, yang akan memungkinkan pengguna untuk memberi kredit pada akun mereka secara sembarangan.
Validasi tanggal dan waktu layak mendapat perhatian khusus karena secara konsisten bermasalah. Saya menguji dengan tanggal yang tidak valid (30 Februari, bulan 13), berbagai format (ISO 8601, stempel waktu Unix, string yang dapat dibaca manusia), tanggal yang jauh di masa lalu atau masa depan, dan kasus tepi zona waktu. Insiden jam 2 pagi yang saya sebutkan di awal? Itu adalah kegagalan validasi tanggal.
Untuk field enum, saya menguji dengan nilai yang valid, nilai yang tidak valid, variasi kasus, dan null. Jika API menerima "aktif" dan "tidak aktif" sebagai nilai status, saya akan mencoba "AKTIF", "Aktif", "tertunda", string kosong, dan null. Masing-masing harus diterima (jika tidak peka huruf) atau ditolak dengan pesan yang jelas yang mencantumkan opsi yang valid.
Validasi Respons: Memastikan Integritas Data
Menguji apa yang kembali sama pentingnya dengan menguji apa yang dimasukkan. Saya telah melihat API yang menerima permintaan dengan sempurna tetapi mengembalikan data yang tidak konsisten, tidak lengkap, atau salah format yang merusak aplikasi klien.
| Skenario Uji | Respons yang Diharapkan | Kesalahan Umum | Tingkat Risiko |
|---|---|---|---|
| Tidak Ada Token Autentikasi | 401 Tidak Terotorisasi | Kembali 500 atau data aktual | Kritis |
| Format Tanggal Tidak Valid | 400 Permintaan Buruk dengan kesalahan yang jelas | Menerima "32/13/2021" dan mogok | Tinggi |
| Kredensial Pengguna yang Salah | 403 Dilarang | Membocorkan kredensial pengguna lain | Tinggi |