💡 Key Takeaways
- Resource Naming: The Foundation That Everyone Gets Wrong
- HTTP Methods and Status Codes: Speak the Language Correctly
- Versioning: Future-Proofing Without the Pain
- Pagination, Filtering, and Sorting: Handling Large Datasets
Tiga tahun yang lalu, saya melihat sebuah startup menghabiskan $2,3 juta dalam pendanaan karena desain API mereka sangat rusak secara fundamental sehingga setiap fitur baru memerlukan penulisan ulang setengah dari basis kode mereka. Saya Sarah Chen, dan saya telah menghabiskan 12 tahun terakhir sebagai arsitek API utama di tiga startup unicorn yang berbeda, merancang sistem yang menangani lebih dari 47 miliar permintaan per bulan. Apa yang saya pelajari adalah bahwa desain REST API bukan tentang mengikuti aturan yang kaku—ini tentang membuat pilihan yang disengaja yang dapat bertumpuk menjadi keunggulan teknis atau utang teknis.
💡 Poin Penting
- Penamaan Sumber Daya: Fondasi yang Salah Dimengerti Semua Orang
- Metode HTTP dan Kode Status: Berbicara dengan Bahasa yang Benar
- Versioning: Menjamin Masa Depan Tanpa Rasa Sakit
- Paginasi, Penyaringan, dan Pengurutan: Menangani Dataset Besar
Sudut pandang telah berubah secara dramatis sejak REST menjadi standar de facto. Pada tahun 2026, kita berhadapan dengan komputasi tepi, aplikasi bertenaga AI yang melakukan ribuan panggilan API per detik, dan pengguna yang mengharapkan waktu respons di bawah 100ms dari mana saja di planet ini. Nasihat lama "hanya mengikuti prinsip REST" tidak lagi mencukupi. Anda memerlukan daftar periksa praktis yang telah teruji di lapangan yang mempertimbangkan realitas modern.
Artikel ini adalah daftar periksa itu. Saya membagikan kerangka kerja yang tepat yang saya gunakan saat merancang API untuk perusahaan yang memproses jutaan pendapatan per hari. Ini bukan praktik terbaik yang bersifat teoretis—ini adalah pola yang memisahkan API yang dapat diskalakan dari API yang runtuh di bawah beratnya sendiri.
Penamaan Sumber Daya: Fondasi yang Salah Dimengerti Semua Orang
Izinkan saya memulai dengan sesuatu yang tampak sepele tetapi menyebabkan lebih banyak masalah hilir daripada hampir segala hal lainnya: penamaan sumber daya. Saya telah meninjau lebih dari 200 desain API dalam karir saya, dan saya memperkirakan bahwa 60% dari mereka memiliki penamaan sumber daya yang tidak konsisten atau membingungkan yang menciptakan masalah berantai.
Berikut adalah prinsip inti: URL Anda harus terbaca seperti kalimat yang menggambarkan hierarki sumber daya. Gunakan kata benda jamak untuk koleksi, jaga penelusuran tetap dangkal (maksimum 2-3 tingkat), dan bersikaplah sangat konsisten. Ketika saya bergabung dengan perusahaan saya saat ini, API mereka memiliki titik akhir seperti /getUser, /user-list, dan /users/fetch—semuanya melakukan hal yang serupa. Kami menghabiskan tiga bulan untuk membongkar kekacauan tersebut.
Pola yang saya sarankan:
- Koleksi:
/api/v1/users,/api/v1/orders,/api/v1/products - Sumber daya spesifik:
/api/v1/users/12345,/api/v1/orders/ord_abc123 - Sub-sumber daya:
/api/v1/users/12345/orders,/api/v1/orders/ord_abc123/items - Tindakan pada sumber daya:
/api/v1/orders/ord_abc123/cancel(POST),/api/v1/users/12345/verify-email(POST)
Perhatikan apa yang hilang? Kata kerja dalam jalur URL (kecuali untuk tindakan non-CRUD). Metode HTTP adalah kata kerjanya. GET /users berarti "ambil pengguna." POST /users berarti "buat pengguna." DELETE /users/123 berarti "hapus pengguna 123." Ini bukan hanya estetika—ini membuat API Anda dapat diprediksi dan mengurangi beban kognitif pada pengembang.
Untuk operasi non-CRUD, saya menggunakan pendekatan pragmatis. Ya, puris akan mengatakan semuanya harus dipetakan ke CRUD, tetapi di dunia nyata, Anda memiliki operasi seperti "batalkan pesanan," "verifikasi email," atau "hitung pengiriman." Saya mewakili ini sebagai permintaan POST ke titik akhir tindakan: POST /orders/123/cancel. Kuncinya adalah konsistensi—dokumen pola Anda dan patuhi secara disiplin.
Satu detail penting lainnya: gunakan kebab-case untuk sumber daya yang terdiri dari beberapa kata (/shipping-addresses, bukan /shippingAddresses atau /shipping_addresses). URL tidak peka huruf besar di banyak konteks, dan kebab-case adalah format yang paling mudah dibaca secara universal. Saya telah melihat insiden produksi yang disebabkan oleh masalah kepekaan huruf besar yang bisa dihindari dengan konvensi sederhana ini.
Metode HTTP dan Kode Status: Berbicara dengan Bahasa yang Benar
Jika penamaan sumber daya adalah kosakata API Anda, metode HTTP dan kode status adalah tata bahasanya. Dan sama seperti dalam bahasa manusia, menggunakan tata bahasa yang salah membuat Anda sulit dipahami—bahkan jika orang dapat akhirnya memahami maksud Anda.
Saya melihat dua pola anti yang umum secara berulang. Pertama, API yang menggunakan POST untuk segalanya karena "itu berhasil." Kedua, API yang mengembalikan 200 OK untuk setiap respons, bahkan kesalahan, dengan status aktual yang terkubur dalam badan respons. Kedua pola ini menciptakan API yang lebih sulit di-cache, lebih sulit untuk di-debug, dan lebih sulit untuk diintegrasikan dengan alat standar.
Berikut adalah rincian saya berdasarkan penggunaan di dunia nyata:
GET: Ambil sumber daya. Harus bersifat idempotent dan aman (tanpa efek samping). Jangan pernah menggunakan GET untuk operasi yang mengubah status—saya tidak peduli jika itu "hanya memperbarui cap waktu terakhir diakses." Itu untuk middleware. Permintaan GET harus dapat di-cache, dan mencampurkan perubahan status merusak asumsi caching. Dalam satu sistem yang saya kerjakan, kami melihat pengurangan beban basis data sebesar 73% hanya dengan menerapkan idempotensi GET dengan benar dan menambahkan header caching HTTP.
POST: Buat sumber daya baru atau memicu tindakan. POST adalah kuda kerja Anda untuk operasi non-idempotent. Saat membuat sumber daya, kembalikan 201 Created dengan header Lokasi yang mengarah ke sumber daya baru. Saat memicu tindakan, kembalikan 200 OK atau 202 Accepted (untuk operasi asinkron) dengan badan respons yang menjelaskan hasilnya.
PUT: Gantikan seluruh sumber daya. Di sinilah banyak pengembang kebingungan. PUT harus menggantikan sumber daya lengkap dengan representasi yang diberikan. Jika Anda mengirim permintaan PUT dengan hanya beberapa bidang, itu adalah satu-satunya bidang yang harus dimiliki sumber daya setelahnya (bidang lain harus disetel ke default atau null). Dalam praktiknya, saya menggunakan PUT dengan hemat—biasanya hanya untuk sumber daya di mana klien benar-benar mengelola kondisi seluruhnya.
PATCH: Memperbarui secara parsial sebuah sumber daya. Ini adalah apa yang kebanyakan pengembang sebenarnya inginkan ketika mereka berpikir bahwa mereka ingin menggunakan PUT. PATCH memungkinkan Anda untuk mengirim hanya bidang yang ingin Anda ubah. Saya biasanya menggunakan JSON Patch (RFC 6902) atau JSON Merge Patch (RFC 7396) untuk format permintaan. Di perusahaan saya saat ini, 94% dari operasi pembaruan kami menggunakan PATCH, bukan PUT.
DELETE: Hapus sumber daya. Kembalikan 204 No Content jika sukses (badan respons tidak diperlukan), atau 200 OK jika Anda mengembalikan informasi tentang penghapusan. Jadikan DELETE idempotent—memanggilnya beberapa kali harus memiliki efek yang sama seperti memanggilnya sekali. Kembalikan 204 bahkan jika sumber daya sudah dihapus.
Untuk kode status, saya menggunakan subset praktis ini yang mencakup 99% skenario:
- 200 OK: GET, PUT, PATCH, atau POST yang berhasil yang mengembalikan data
- 201 Created: POST yang berhasil yang membuat sumber daya
- 202 Accepted: Permintaan diterima untuk pemrosesan asinkron
- 204 No Content: DELETE atau pembaruan yang berhasil tanpa badan respons
- 400 Bad Request: Klien mengirimkan data yang tidak valid (dengan pesan kesalahan yang rinci)
- 401 Unauthorized: Autentikasi diperlukan atau gagal
- 403 Forbidden: Sudah terautentikasi tetapi tidak diberi wewenang untuk sumber daya ini
- 404 Not Found: Sumber daya tidak ada
- 409 Conflict: Permintaan bertentangan dengan keadaan saat ini (misalnya, email duplikat)
- 422 Unprocessable Entity: Validasi gagal (saya lebih memilih ini daripada 400 untuk kesalahan validasi)
- 429 Too Many Requests: Batas kecepatan terlampaui
- 500 Internal Server Error: Sesuatu yang rusak di pihak kami
- 503 Service Unavailable: Pemadaman sementara atau pemeliharaan
Poin kunci: kode status adalah untuk semantik tingkat HTTP, badan respons adalah untuk detail tingkat aplikasi. Respons 400 harus selalu berarti "Anda mengirimkan data yang buruk," tetapi badan respons menjelaskan dengan tepat apa yang salah dengan bidang mana.
Versioning: Menjamin Masa Depan Tanpa Rasa Sakit
Saya telah mengalami tiga migrasi versi API yang besar, dan masing-masing mengajarkan saya sesuatu yang menyakitkan tentang apa yang tidak boleh dilakukan. Yang terburuk adalah migrasi v1 ke v2 yang memakan waktu 18 bulan dan memerlukan pengaturan pembaruan di 47 aplikasi klien. Kami kehilangan dua pelanggan besar selama proses itu karena tim integrasi mereka tidak dapat mengikuti perubahan.
| Pendekatan | Polanya URL | Skalabilitas | Kemudahan Pemeliharaan |
|---|---|---|---|
| RESTful (Direkomendasikan) | /users/{id}/orders | Cemerlang - Hierarki yang jelas, dapat di-cache | Tinggi - Pola yang dapat diprediksi |
| RPC-Style (Anti-pola) | /getUser, /fetchOrders | Buruk - Tidak ada caching, berbasis kata kerja | Rendah - Penamaan yang tidak konsisten |