GraphQL: Masa Bulan Madu di Enterprise Telah Berakhir
(johnjames.blog)- GraphQL berusaha menyelesaikan masalah permintaan data berlebih, tetapi di sebagian besar lingkungan enterprise, masalah ini sebenarnya sudah diselesaikan dengan cara lain
- Dalam sistem perusahaan yang sudah umum memakai arsitektur BFF(Backend for Frontend), keunggulan utama GraphQL jadi jauh berkurang
- Kompleksitas implementasi, observabilitas yang menurun, masalah caching, batasan ID, serta repotnya penanganan file membuat biayanya membesar di lingkungan produksi nyata
- REST lebih sederhana dan cepat, serta lebih mudah untuk penanganan error dan onboarding, sehingga lebih efisien untuk lingkungan tim skala besar
- Kesimpulannya, GraphQL berguna dalam situasi tertentu, tetapi bagi kebanyakan enterprise merupakan pilihan yang berlebihan
Masalah yang Ingin Diselesaikan GraphQL
- Tujuan utama GraphQL adalah mencegah overfetching (permintaan data berlebih yang tidak diperlukan)
- Klien dapat meminta hanya field yang dibutuhkan sehingga mengurangi pengiriman data yang tidak perlu
- Ada keuntungan karena backend tidak perlu diubah setiap kali muncul kebutuhan UI baru
- Namun di lingkungan nyata, struktur ideal ini tidak cocok dengan realitas yang kompleks
Overfetching Sudah Diselesaikan dengan BFF
- Sebagian besar frontend enterprise menggunakan lapisan BFF(Backend for Frontend)
- Lapisan ini menggabungkan data sesuai kebutuhan UI, menyatukan beberapa panggilan downstream, dan menyembunyikan kompleksitas backend
- BFF berbasis REST sudah bisa mengembalikan hanya data yang diperlukan, sehingga keunggulan GraphQL menjadi tumpang tindih
- Jika lapisan GraphQL mengambil data dari REST API, overfetching hanya berpindah satu lapisan ke bawah
- GraphQL bisa berguna ketika beberapa halaman berbagi endpoint yang sama, tetapi
- manfaat itu pada akhirnya hanya setara dengan menukar beberapa kilobyte penghematan dengan beban setup dan pemeliharaan yang lebih besar
Kompleksitas Implementasi dan Turunnya Produktivitas
- GraphQL membutuhkan waktu implementasi yang jauh lebih lama dan lebih kompleks dibanding REST
- Perlu pekerjaan tambahan seperti mendefinisikan schema, type, resolver, dan data source
- Ada juga beban untuk menjaga sinkronisasi antara schema dan klien
- GraphQL mengoptimalkan konsumsi (kenyamanan klien), tetapi mengorbankan produksi (kecepatan pengembangan server)
- Di lingkungan enterprise, kecepatan produksi dan kesederhanaan lebih penting
Masalah Observabilitas dan Monitoring
- Sistem HTTP status code pada GraphQL tidak konsisten
- Respons 200 pun bisa memuat error, sehingga sulit membedakan sukses/gagal saat monitoring
- Pada REST, 2XX/4XX/5XX dipisahkan dengan jelas sehingga filtering dashboard lebih intuitif
- Memang bisa dikustomisasi di Apollo dan sejenisnya, tetapi itu menimbulkan setup tambahan dan beban mental
- Saat menangani insiden di produksi, identifikasi masalah lebih sulit dan lebih kompleks dibanding REST
Batasan Praktis Caching
- Normalized caching milik Apollo secara teori kuat, tetapi dalam praktiknya rapuh dan kompleks
- Query yang hanya berbeda satu field pun diperlakukan terpisah sehingga perlu pengaitan manual
- Debugging cache berkembang menjadi masalah tersendiri
- Sebaliknya, REST cukup melakukan caching pada seluruh respons sehingga lebih stabil dan mudah dipelihara
Masalah Batasan Field ID
- Apollo mengasumsikan semua objek memiliki field id atau _id
- Banyak API enterprise tidak memiliki ID unik, atau ID tersebut bukan identifier global
- Agar sesuai, BFF harus menambahkan logika pembuatan ID lokal
- Akibatnya, field dan logika yang tidak perlu bertambah, sehingga efek pengurangan overfetching ikut tereduksi
Inefisiensi Upload dan Download File
- GraphQL tidak cocok untuk menangani data biner
- Dalam praktiknya, sistem akan mengembalikan URL download, lalu file tetap dikirim lewat REST
- Jika data besar seperti PDF dimasukkan ke respons GraphQL, kinerja akan menurun
- Karena itu, ideal GraphQL sebagai “single API” pun runtuh
Onboarding dan Learning Curve
- Sebagian besar developer sudah berpengalaman dengan REST, tetapi GraphQL perlu dipelajari
- Perlu mempelajari konsep baru seperti schema, resolver, susunan query, aturan caching, dan penanganan error
- Ini menyebabkan kecepatan onboarding tim menurun
- REST adalah pendekatan yang “membosankan tetapi sangat skalabel” sehingga cocok untuk tim besar
Kompleksitas Penanganan Error
- Respons error GraphQL itu rumit, dengan nullable field, partial data, array errors, dan extended status code
- Perlu melacak resolver mana yang gagal
- REST cukup dibedakan dengan 400/500 sehingga lebih mudah dipahami dan di-debug
Kesimpulan: GraphQL adalah Teknologi Niche
- GraphQL adalah alat yang valid dalam situasi tertentu
- Namun di sebagian besar lingkungan enterprise, masalahnya sudah diselesaikan dengan BFF dan REST
- Tantangan utama bukan overfetching, melainkan observabilitas, keandalan, dan kecepatan
- Pada akhirnya, GraphQL menyelesaikan masalah yang sempit sambil menciptakan kompleksitas yang lebih luas
- Kesimpulannya adalah, “GraphQL tidak buruk, tetapi dalam kebanyakan kasus memang tidak diperlukan”
2 komentar
Komentar Hacker News
Saya tidak setuju dengan tulisan yang menyebut masalah utama GraphQL adalah overfetching
Menurut saya, keunggulan sebenarnya adalah (a) memaksa kontrak ketat berbasis tipe, dan (b) evolusi skema jadi jauh lebih mudah
Berkat sistem tipe, input dan output selalu mengikuti bentuk yang sudah didefinisikan, dan jika memakai tipe skalar kustom (mis. nomor telepon, email, dll.), bug serta isu keamanan bisa berkurang drastis
Selain itu, penambahan field baru atau penghapusan field lama sudah terstandarisasi, jadi beban kognitif di sisi server maupun klien lebih rendah
Alasan saya memakai GraphQL adalah komposisi dan evolusi API. Khususnya pada sistem skala besar dengan struktur M:N, alur “klien mendeskripsikan kebutuhannya → server mengomposisikan → layanan domain menyelesaikan” jauh lebih mudah dikelola dalam jangka panjang
Jika dipadukan dengan observability yang baik, ini menjadi fondasi yang kuat untuk akses data
Alasan lainnya adalah resolver reuse dan federation yang mudah. Dalam REST, ini cukup merepotkan
Evolusi skema juga ditangani dengan baik oleh Protobuf
Keunggulan nyata GraphQL adalah bisa mengomposisikan data UI dari potongan-potongan kecil
Dengan memanfaatkan fragment colocation seperti di video ini, kita bisa mengubah komponen turunan tanpa memengaruhi bagian lain
Karena query dibuat otomatis berbasis fragment, risiko komponen lain rusak saat field dihapus juga berkurang
Jika skalanya kecil atau kecepatan pengembangan tidak terlalu penting, GraphQL bisa terlihat seperti investasi berlebihan
Colocation itu konsep yang benar-benar revolusioner, tetapi Apollo hampir tidak pernah menyinggungnya
Dokumentasi Relay masih kurang, tetapi konsep Entrypoint sangat bagus
Hanya saja implementasi graphql-codegen kurang baik dalam hal kompatibilitas plugin, jadi kami harus membuat plugin sendiri
Konsistensi di seluruh ekosistem masih kurang
Pernyataan bahwa overfetching adalah masalah inti GraphQL itu berlebihan
Saya menganggap GraphQL sebagai alat yang menangani impedance mismatch di level klien, seperti ORM menanganinya di sisi lain
Memakainya tanpa tooling berbasis compiler seperti Relay adalah antipola
Sekarang AI bisa membuat data layer secara otomatis, jadi kebutuhan akan GraphQL tampaknya mulai berkurang
Pengalaman pengembangnya (DevEx) sangat baik, misalnya bisa membuatkan otomatis saat kita memilih field yang tidak ada
Kelambatan web modern kebanyakan disebabkan oleh pengiriman data berlebihan. Banyak aplikasi di dunia nyata berjalan dengan efisiensi di bawah 0,5%
Saya sudah memakai GraphQL sejak 2016
Pada dasarnya GraphQL adalah spesifikasi RPC. Implementasinya berupa peta “Action(Args) → ResultType” di server
Alih-alih banyak endpoint seperti REST, GraphQL berjalan lewat satu endpoint
/querymenggunakan peta resolverPada akhirnya, ini tetap struktur dengan input dan output yang didefinisikan oleh tipe, seperti OpenAPI atau gRPC
Apollo sedikit membaik setelah menambahkan fragment masking, tetapi cara berpikir yang berpusat pada Relay tetap penting
lalu backend mengubahnya menjadi satu query SQL untuk diproses
Resolver seharusnya hanya dipakai secara pengecualian untuk data yang tidak bisa diambil langsung dari DB
Dulu saat memimpin tim, FE menginginkan GraphQL sehingga kami mengadopsinya
Hasilnya, tiap halaman mengambil semua data lewat satu query raksasa, dan saat memodifikasi, seluruh JSON blob dikirim ulang
Aplikasinya memang berjalan, tetapi akhirnya kode itu hilang ketika perusahaan berpivot
Rasanya banyak proyek GraphQL pada praktiknya berakhir sebagai implementasi formalitas seperti ini
Alur autentikasi (auth) di GraphQL adalah salah satu tantangan terbesar
Karena resolver dipanggil dalam berbagai konteks, semua kasus harus dipertimbangkan
Kompleksitas dan biaya berpikirnya terlalu besar, sehingga pada akhirnya field-field malah dikunci
Saya sampai membuat graphql-autharoo sendiri, tetapi itu pun tidak cukup
Kebanyakan fitur sebenarnya bisa diimplementasikan dengan lebih sederhana tanpa GraphQL
Karena perlu menambahkan izin rinci ke setiap resource GraphQL, query tidak akan berjalan sampai seluruh resource diperbarui
Bebannya sedemikian besar sampai muncul komentar seperti “lebih baik bikin ulang dengan REST”
Menurut saya lebih baik memakai framework server yang matang daripada merakit semuanya sendiri
GraphQL kelihatannya bagus di permukaan, tetapi pada praktiknya semakin sulit dipelihara seiring waktu
Seperti banyak teknologi lain, pada akhirnya ini mengajarkan bahwa roda tetaplah roda
Keunggulan GraphQL adalah cukup menambahkan field ke skema, lalu semua klien bisa langsung meng-query-nya
Permintaan FE seperti “tolong tambahkan field ini juga” pun hilang, sehingga kolaborasi jadi lebih sederhana
Selain itu, mudah juga membuat snapshot skema untuk mendeteksi perubahan dalam integration test
Saya merasa ini lebih konsisten daripada REST, tetapi itu hanya pengalaman pribadi
Karena permintaan berantai dari A sampai E dimungkinkan, penurunan performa dan keterikatan antara frontend dan struktur data jadi makin parah
React juga kini mengutamakan SSR berbasis framework dan server component
Pada akhirnya arahnya adalah TypeScript menyatukan klien dan server
Saya penasaran bagaimana GraphQL mencegah masalah beban DB atau query yang tidak efisien
Bukankah query jahat bisa membuat status internal meledak?
REST terlalu membosankan, jadi saya sedang mencoba GraphQL
Saya suka bahwa server dan klien bisa sepakat soal request dan response saat compile time
Saya harap blog-blog tidak hanya berkata “ini jelek”, tetapi juga menawarkan teknologi alternatif
Keduanya sama-sama menyelesaikan masalah kontrak klien-server dengan baik
Meski ada kelebihan dan kekurangannya, menurut saya pendekatan yang merancang data dan kontrol akses di level skema, lalu menambahkannya ke Rest API setiap kali ada sesuatu yang baru alih-alih nanti malah mengembalikan semuanya, terlihat lebih baik. Kekurangannya memang jelas, tetapi kelebihannya juga jelas haha