Dalam desain arsitektur sistem terdistribusi, API bukan sekadar saluran interaksi sistem; API adalah kontrak yang menghubungkan berbagai tumpukan teknologi, budaya organisasi, dan bahkan era pengembangan. Dalam detail desain API RESTful, satu topik yang terkesan minor memicu perdebatan tanpa akhir: Haruskah nama bidang JSON menggunakan camelCase atau snake_case?
Ini bukan sekadar pilihan estetika. Ini menyentuh "ketidakcocokan impedansi" antara lapisan persistensi backend dan lapisan presentasi frontend, melibatkan kinerja serialisasi, efisiensi transmisi jaringan, Pengalaman Pengembang (DX), dan psikologi kognitif.
Berdasarkan sejarah bahasa pemrograman, mekanisme implementasi teknis yang mendasari, dan keputusan arsitektur raksasa industri seperti Google dan Stripe, artikel ini menyajikan panduan keputusan tingkat ahli.
1. Asal Mula Historis: Sebuah Pilihan Semiotik
Untuk memahami perdebatan ini, kita harus menelusuri evolusi bahasa komputer. Konvensi penamaan tidak muncul begitu saja; mereka adalah produk dari keterbatasan perangkat keras dan budaya komunitas dari era tertentu.
Asal Mula snake_case: C dan Filosofi Unix
Popularitas snake_case (misalnya, user_id) berasal dari C dan Unix pada tahun 1970-an. Meskipun keyboard awal (seperti Teletype Model 33) memiliki tombol shift, banyak kompiler awal yang tidak peka huruf besar-kecil. Untuk membedakan kata dengan jelas pada tampilan resolusi rendah, pemrogram memperkenalkan garis bawah untuk mensimulasikan spasi dalam bahasa alami. Kebiasaan ini menjadi sangat mengakar dalam standar basis data SQL. Hingga hari ini, gaya penamaan kolom default untuk PostgreSQL dan MySQL tetap snake_case, meletakkan dasar untuk gesekan pemetaan di masa depan antara API dan basis data.
Kebangkitan camelCase: Hegemoni Java dan JavaScript
camelCase (misalnya, userId) muncul bersama Pemrograman Berorientasi Objek (Smalltalk, C++, Java). Java menetapkan standar industri "PascalCase untuk kelas, camelCase untuk metode/variabel." Titik balik yang menentukan adalah kelahiran **JavaScript**. Meskipun JSON berasal dari literal objek JS, pustaka standar JS (misalnya, getElementById) mengadopsi camelCase secara menyeluruh. Ketika AJAX dan JSON menggantikan XML sebagai format pertukaran data yang dominan, camelCase memperoleh status "native" di domain Web.
2. Konflik Utama: Ketidakcocokan Impedansi Tumpukan Teknologi
Ketika data mengalir antar bahasa yang berbeda, ia pasti akan mengalami "ketidakcocokan impedansi."
Perspektif Backend (Python/Ruby/SQL)
Di backend, komunitas Python (PEP 8) dan Ruby sangat merekomendasikan snake_case.
- Python/Django/FastAPI: Model Pydantic Anda biasanya sesuai langsung dengan struktur tabel basis data:
class UserProfile(BaseModel):
first_name: str # Python convention
last_name: strJika API mewajibkan camelCase, Anda harus mengonfigurasi alias atau konverter di lapisan serialisasi. Meskipun bisa dilakukan, ini menambah lapisan logika pemetaan.
- Basis Data SQL: Sebagian besar nama kolom basis data menggunakan
snake_case. Jika API menggunakancamelCase, lapisan ORM harus secara konsisten menangani konversi. - Pilihan Stripe: Alasan Stripe dan GitHub dengan tegas memilih
snake_casesebagian besar karena arsitektur awal mereka dibangun di atas tumpukan Ruby. Mengekspos model internal secara langsung memastikan konsistensi backend.
Perspektif Frontend (JavaScript/TypeScript)
Di browser, camelCase adalah penguasa mutlak.
- Fragmentasi Gaya Kode: Jika API mengembalikan
snake_case, kode frontend menjadi tidak konsisten:
const user = await fetchUser();
console.log(user.first_name); // Violates ESLint camelcase rule
render(user.email_address);ESLint akan menandainya sebagai peringatan, memaksa pengembang untuk menonaktifkan aturan atau mengonversi data segera setelah diterima.
- Kesulitan Destructuring: Dalam pengembangan JS/TS modern, destructuring objek lazim. Jika bidang-bidang menggunakan
snake_case, mereka harus diganti namanya selama destructuring untuk menghindari pencemaran cakupan lokal:
// Verbose renaming
const { first_name: firstName, last_name: lastName } = response.data;Ini meningkatkan kode boilerplate dan kemungkinan kesalahan.
3. Mitos Kinerja: Serialisasi dan Transmisi Jaringan
Mengenai kinerja, ada dua mitos umum: **"Konversi nama bidang terlalu lambat"** dan **"Garis bawah meningkatkan ukuran payload."** Mari kita jelaskan dengan data.
Mitos 1: Overhead Konversi Runtime
- Bahasa Dinamis: Dalam Python atau Ruby, mengonversi nama bidang melalui penggantian regex pada setiap permintaan memang mengonsumsi CPU. Namun, framework modern (seperti Pydantic v2, yang ditulis ulang dalam Rust) meminimalkan overhead ini melalui pemetaan Skema yang telah dihitung sebelumnya.
- Bahasa Statis (Go/Java/Rust): Ini secara efektif "tanpa biaya." Tag struct Go (
json:"firstName") atau cache pemetaan Java Jackson ditentukan pada waktu kompilasi atau startup. Eksekusi runtime melibatkan penyalinan byte sederhana, bukan perhitungan dinamis.
Catatan: Jangan pernah melakukan konversi rekursif global di frontend (thread utama browser) menggunakan interceptor (misalnya, Axios). Untuk respons besar, ini menyebabkan jank halaman dan churn memori. Kesimpulan: Backend harus menangani konversi.
Mitos 2: Ukuran Transmisi dan Kompresi
Secara teori, `first_name` satu byte lebih panjang dari `firstName`. Namun, dengan kompresi **Gzip** atau **Brotli** diaktifkan (konfigurasi HTTP standar), perbedaan ini secara virtual menghilang.
- Prinsip: Algoritma kompresi bergantung pada "referensi string duplikat." Dalam array JSON, kunci sangat berulang. Algoritma menyimpan
first_namedalam kamus pada saat pertama kali ditemukan dan mengganti kemunculan selanjutnya dengan pointer kecil. - Tolok Ukur: Pengujian menunjukkan bahwa di bawah Gzip level 6, perbedaan ukuran antara kedua gaya biasanya antara 0,5% dan 1%. Kecuali Anda mentransmisikan data melalui tautan satelit, ini bukan masalah.
4. Pengalaman Pengembang (DX) dan Psikologi Kognitif
Arsitektur bukan hanya tentang mesin; ini tentang manusia.
- Keterbacaan snake_case: Psikologi kognitif menunjukkan bahwa garis bawah memberikan pemisahan visual yang jelas.
parse_db_xmldiproses oleh otak lebih cepat daripadaparseDbXml, terutama saat berhadapan dengan akronim berurutan (misalnya,XMLHTTPRequestvsXmlHttpRequest). Ini adalah salah satu alasan dokumentasi Stripe dianggap sangat mudah dibaca. - Konsistensi camelCase: Kondisi aliran (flow state) yang dihasilkan oleh konsistensi full-stack lebih penting. Untuk tim JS/TS full-stack, menggunakan
camelCasedi seluruh frontend dan backend memungkinkan penggunaan kembali definisi tipe secara langsung (Interface/Zod Schema), sepenuhnya menghilangkan beban kognitif dari "terjemahan mental".
5. Standar Industri dan Rasional
| Organisasi | Pilihan | Logika Inti & Latar Belakang |
|---|---|---|
| camelCase | Panduan Google API (AIP-140) mewajibkan lowerCamelCase untuk JSON. Bahkan jika definisi Protobuf internal menggunakan snake_case, lapisan konversi eksternal secara otomatis beralih ke camelCase agar selaras dengan ekosistem Web. |
|
| Microsoft | camelCase | Dengan .NET Core merangkul open source dan penemuan TypeScript, Microsoft sepenuhnya beralih ke standar Web, meninggalkan PascalCase awal. |
| Stripe | snake_case | Perusahaan tumpukan Ruby yang khas. Mereka menyamarkan perbedaan dengan menyediakan SDK Klien yang sangat kuat. Saat Anda menggunakan Node SDK, meskipun snake_case ditransmisikan, tanda tangan metode SDK biasanya mengikuti konvensi JS. |
| JSON:API | camelCase | Spesifikasi yang didorong oleh komunitas secara eksplisit merekomendasikan camelCase, mencerminkan konsensus komunitas Web. |
6. Saran Arsitektur Mendalam: Dekopling dan DTO
Sebuah anti-pola umum adalah "Pass-through": secara langsung menserialisasi entitas basis data untuk mengembalikannya.
- Jika Anda melakukan ini, dan kolom DB Anda adalah
snake_case, API Anda menjadisnake_case. - Risiko: Ini melanggar prinsip penyembunyian informasi, mengekspos struktur tabel, dan menciptakan kopling yang kuat antara API dan DB. Jika DB diganti namanya, API akan rusak.
Praktik Terbaik: Perkenalkan lapisan DTO (Data Transfer Object). Terlepas dari bagaimana basis data yang mendasari dinamai, Anda harus mendefinisikan kontrak API independen (DTO). Karena Anda mendefinisikan DTO, mengapa tidak mendefinisikannya sebagai camelCase untuk mematuhi standar Web? Alat pemetaan modern (MapStruct, AutoMapper, Pydantic) menangani konversi ini dengan mudah.
7. Melihat ke Depan: GraphQL dan gRPC
GraphQL: Komunitas hampir 100% merangkul camelCase. Jika tim Anda berencana memperkenalkan GraphQL di masa mendatang, mendesain API REST dengan camelCase sekarang adalah strategi "kompatibilitas ke depan" yang bijaksana.
gRPC: Standar Protobuf menetapkan: file .proto menggunakan snake_case untuk definisi bidang, tetapi mereka harus dikonversi ke camelCase saat dipetakan ke JSON. Ini adalah solusi standar Google untuk lingkungan multi-bahasa.
8. Ringkasan dan Matriks Keputusan
Tidak ada yang benar atau salah secara mutlak, hanya ada pertukaran (trade-off). Berikut adalah kerangka keputusan akhir:
Rekomendasi: Default ke camelCase
Untuk sebagian besar API RESTful tujuan umum yang baru dan menghadap klien Web/Aplikasi, camelCase sangat direkomendasikan.
Alasan: Selaras dengan dominasi JSON/JavaScript/TypeScript, merangkul kebiasaan 90% konsumen.
Alat: Dapatkan dukungan terbaik dari generator kode OpenAPI, Swagger UI, dan IDE modern.
Kapan menggunakan snake_case?
1. Konsumen Spesifik: Pengguna utama API adalah ilmuwan data Python atau ops sistem (Curl/Bash).
2. Sistem Lama (Legacy Systems): API yang ada sudah menggunakan snake_case. Konsistensi > Praktik Terbaik. Jangan mencampur gaya dalam sistem yang sama.
3. Ekstremisme Kecepatan Backend: Menggunakan Python/Ruby tanpa sumber daya untuk memelihara lapisan DTO, secara langsung meneruskan model basis data.
Tabel Keputusan
| Dimensi | Gaya yang Direkomendasikan |
|---|---|
| Frontend Web / Aplikasi Seluler | camelCase (Impedansi nol, keamanan tipe) |
| Analisis Data / Komputasi Ilmiah | snake_case (Sesuai kebiasaan Python/R) |
| Backend Node.js / Go / Java | camelCase (Dukungan native atau pustaka sempurna) |
| Backend Python / Ruby | camelCase (Konverter direkomendasikan) atau snake_case (Hanya untuk alat internal) |
| Tim Full-Stack | Semakin tinggi tingkat full-stack, semakin direkomendasikan camelCase |
Esensi desain API adalah empati. Dalam konteks API Web, mengenkapsulasi kompleksitas di backend (menangani pemetaan) dan menyerahkan kenyamanan kepada pengguna (mematuhi kebiasaan JS) adalah pilihan yang mencerminkan profesionalisme yang lebih besar.
