- GraphQL, aşırı veri isteme sorununu çözmeye çalışıyor ancak çoğu kurumsal ortamda bu sorun zaten başka yöntemlerle çözülmüş durumda
- BFF (Backend for Frontend) mimarisinin yaygın olduğu kurumsal sistemlerde GraphQL’in başlıca avantajları büyük ölçüde azalıyor
- Uygulama karmaşıklığı, gözlemlenebilirliğin azalması, önbellekleme sorunları, ID kısıtları, dosya işlemenin zorluğu gibi nedenlerle gerçek üretim ortamlarında maliyet büyüyor
- REST basit ve hızlıdır; hata işleme ve onboarding daha kolay olduğu için büyük ekiplerde daha verimlidir
- Sonuç olarak GraphQL, belirli durumlarda yararlı olsa da çoğu kurumsal yapı için aşırı bir tercih olarak değerlendiriliyor
GraphQL’in çözmeye çalıştığı sorun
- GraphQL’in temel amacı overfetching (gereksiz fazla veri isteme) sorununu önlemek
- İstemci yalnızca ihtiyaç duyduğu alanları isteyerek gereksiz veri aktarımını azaltır
- Yeni UI gereksinimlerinde her seferinde backend değişikliği gerekmemesi avantaj sağlar
- Ancak gerçek dünyada bu ideal yapı, karmaşık pratiklerle örtüşmüyor
BFF ile zaten çözülmüş overfetching
- Kurumsal frontend’lerin çoğu BFF (Backend for Frontend) katmanı kullanır
- Veriyi UI’a uygun biçimde birleştirir, birden fazla downstream çağrısını toplar ve backend karmaşıklığını gizler
- REST tabanlı BFF zaten yalnızca gerekli veriyi döndürebildiği için GraphQL’in avantajı tekrara düşer
- GraphQL katmanı veriyi REST API’lerden alıyorsa, overfetching yalnızca bir katman aşağı taşınmış olur
- Birden fazla sayfa aynı endpoint’i paylaştığında GraphQL faydalı olabilir, ancak
- bunun getirisi çoğu zaman birkaç kilobayt tasarrufu için daha fazla kurulum ve bakım yükü üstlenmek anlamına gelir
Uygulama karmaşıklığı ve üretkenlik kaybı
- GraphQL, REST’e göre çok daha fazla uygulama süresi ve karmaşıklık gerektirir
- Şema, tipler, resolver’lar ve veri kaynakları için ek tanımlar gerekir
- Şema ile istemci arasındaki senkronizasyonu koruma yükü vardır
- GraphQL, tüketimi (istemci rahatlığını) optimize ederken üretimi (sunucu geliştirme hızını) feda eder
- Kurumsal ortamlarda geliştirme hızı ve sadelik daha önemlidir
Gözlemlenebilirlik ve izleme sorunları
- GraphQL’in HTTP durum kodu yapısı tutarsızdır
- 200 yanıtının içinde bile hata bulunabildiğinden, izleme sırasında başarı/başarısızlık ayrımı zorlaşır
- REST’te 2XX/4XX/5XX ayrımı nettir ve dashboard filtreleme daha sezgiseldir
- Apollo gibi araçlarda özelleştirme mümkündür, ancak bu ek ayar ve zihinsel yük getirir
- Üretimde arıza müdahalesi sırasında REST’e kıyasla sorunu anlamak daha zor ve daha karmaşıktır
Önbelleklemenin pratik sınırları
- Apollo’nun normalized caching yaklaşımı teoride güçlü olsa da pratikte kırılgan ve karmaşıktır
- Yalnızca tek bir alanı farklı olan sorgular bile ayrı ele alınır ve manuel bağlama gerekir
- Önbellek hata ayıklama başlı başına ayrı bir soruna dönüşür
- REST ise tüm yanıtı önbelleğe alarak daha istikrarlı ve bakımı kolay bir yapı sunar
ID alanı kısıtlarının yarattığı sorun
- Apollo, her nesnede id veya _id alanı bulunduğunu varsayar
- Oysa birçok kurumsal API’de benzersiz ID yoktur ya da bunlar küresel tanımlayıcı değildir
- Buna uyum sağlamak için BFF’nin yerel ID üretim mantığı eklemesi gerekir
- Sonuçta gereksiz alanlar ve ek mantık artar, overfetching’i azaltmanın faydası da dengelenir
Dosya yükleme ve indirmedeki verimsizlik
- GraphQL, ikili veri işlemeye uygun değildir
- Pratikte indirme URL’si döndürülür ve dosya REST ile aktarılır
- PDF gibi büyük veriler GraphQL yanıtına eklenirse performans düşer
- Bu da GraphQL’in “tek API” idealini bozar
Onboarding ve öğrenme eğrisi
- Geliştiricilerin çoğu REST konusunda deneyimlidir, ancak GraphQL öğrenme gerektirir
- Şema, resolver, sorgu yapısı, önbellekleme kuralları ve hata işleme gibi yeni kavramlar öğrenilmelidir
- Bu nedenle ekip onboarding hızı düşer
- REST, “sıkıcı ama ölçeklenebilir” bir yaklaşım olarak büyük ekipler için daha uygundur
Hata işlemenin karmaşıklığı
- GraphQL hata yanıtları; nullable alanlar, partial data,
errors dizisi, genişletilmiş durum kodları gibi unsurlar nedeniyle karmaşıktır
- Hangi resolver’ın başarısız olduğunu ayrıca izlemek gerekir
- REST’te ise 400/500 ayrımıyla yapı daha basittir ve anlama ile hata ayıklama daha kolaydır
Sonuç: GraphQL niş bir teknoloji
- GraphQL, belirli durumlarda geçerli bir araçtır
- Ancak çoğu kurumsal ortamda sorunlar zaten BFF ve REST ile çözülmüştür
- Asıl zorluk overfetching değil, gözlemlenebilirlik, güvenilirlik ve hızdır
- Sonuç olarak GraphQL, dar bir problemi çözerken daha geniş bir karmaşıklık yaratır
- Varmak istenen sonuç şu: GraphQL kötü değil ama çoğu durumda gerekli de değil
2 yorum
Artıları ve eksileri vardır ama veriyi ve erişim kontrolünü şema seviyesinde tasarlamak, bir şey ekleneceği zaman her seferinde Rest API'ye ekleyip sonra en sonunda hepsini döndürmekten daha iyi görünüyor. Dezavantajları açık ama avantajları da açık :)
Hacker News görüşleri
GraphQL'nin temel sorununun overfetching olduğunu söyleyen yazıya katılmıyorum
Bana göre asıl avantajları (a) katı tip tabanlı sözleşmeyi zorunlu kılması, (b) şema evriminin çok daha kolay olması
Tip sistemi sayesinde girdi ve çıktılar her zaman tanımlı bir biçime uyar; özel skaler tipler (ör. telefon numarası, e-posta vb.) kullanıldığında hata ve güvenlik sorunları büyük ölçüde azaltılabilir
Ayrıca yeni alan ekleme ya da mevcut alanları kullanımdan kaldırma süreci standartlaştırılmıştır; bu da hem sunucu hem istemci tarafında bilişsel yükü azaltır
GraphQL kullanma nedenim API bileşimi ve evrimi. Özellikle M:N yapısına sahip büyük sistemlerde “istemci ihtiyacını tanımlar → sunucu bunu birleştirir → domain servisleri çözer” akışı uzun vadede çok daha yönetilebilir oluyor
İyi bir observability ile birleştiğinde veri erişimi için güçlü bir temel haline geliyor
Bir diğeri de resolver yeniden kullanımı ve federation kolaylığı. REST'te bu epey zahmetli
Şema evrimini Protobuf da iyi yönetiyor
GraphQL'nin asıl avantajı UI verilerini küçük parçalardan birleştirebilmek
Şu videodaki gibi fragment colocation kullanılırsa, alt bileşenleri değiştirseniz bile diğer kısımlar etkilenmiyor
Sorgular fragment tabanlı olarak otomatik üretildiği için, bir alan kaldırıldığında başka bileşenlerin bozulma riski de azalıyor
Ölçek küçükse ya da hızlı geliştirme kritik değilse GraphQL fazla yatırım gibi görünebilir
Colocation gerçekten devrim niteliğinde bir fikir ama Apollo bundan neredeyse hiç söz etmedi
Relay'nin dokümantasyonu hâlâ yetersiz ama Entrypoint kavramı mükemmel
Ancak graphql-codegen'in uygulamasında eklenti uyumluluğu zayıf olduğu için biz kendi eklentimizi yazmak zorunda kaldık
Ekosistem genelinde tutarlılık eksik
Overfetching'in GraphQL'nin temel sorunu olduğu iddiası abartılı
Bence GraphQL, ORM'lerin çözdüğü impedance mismatch problemini istemci seviyesinde ele alan bir araç
Relay gibi derleyici tabanlı araçlar olmadan kullanmak bir antipattern
Günümüzde yapay zeka veri katmanını otomatik ürettiği için GraphQL'ye duyulan ihtiyaç azalıyor gibi görünüyor
Var olmayan alanları seçtiğinizde bunları otomatik oluşturması gibi özelliklerle geliştirici deneyimi (DevEx) çok iyi
Modern web'in yavaşlamasının büyük kısmı aşırı veri taşınmasından kaynaklanıyor. Gerçekten de birçok uygulama %0,5'in altında verimle çalışıyor
2016'dan beri GraphQL kullanıyorum
Özünde GraphQL bir RPC spec'i. Sunucudaki “Action(Args) → ResultType” haritası olarak uygulanıyor
REST'in birden çok endpoint'i yerine GraphQL, tek bir
/queryendpoint'inde resolver haritası üzerinden çalışıyorSonuçta OpenAPI ya da gRPC gibi, girdi ve çıktının tiplerle tanımlandığı bir yapı
Apollo fragment masking ekleyince biraz ilerleme oldu ama hâlâ Relay merkezli düşünce önemli
ve backend'in bunu tek bir SQL sorgusuna dönüştürüp işlemesi durumunda ulaşıyor
Resolver'lar yalnızca veritabanından doğrudan alınamayan veriler için istisnai olarak kullanılmalı
Eskiden bir ekibe liderlik ederken FE GraphQL istediği için bunu devreye almıştık
Sonuçta her sayfa için tüm veriyi alan tek bir dev sorgu yazıldı ve değişikliklerde tüm JSON blob yeniden gönderildi
Uygulama çalışıyordu ama şirket pivot edince o kod da kayboldu
Gerçekte birçok GraphQL projesi bu şekilde yalnızca biçimsel bir uygulama olarak kalıyor gibi görünüyor
GraphQL'de kimlik doğrulama (auth) akışı en büyük zorluklardan biri
Resolver'lar çok farklı bağlamlarda çağrılabildiği için her olasılığı hesaba katmak gerekiyor
Karmaşıklık ve zihinsel maliyet o kadar artıyor ki sonunda alanları kilitlemeye başlıyorsunuz
Hatta graphql-autharoo'yu kendim yaptım ama yeterli olmadı
Çoğu özellik GraphQL olmadan daha basit şekilde uygulanabiliyor
Her GraphQL kaynağına ince ayarlı izinler eklemek gerektiğinden, tüm kaynak güncellenene kadar sorgu çalışmıyor
Yük öyle büyük ki “bunu REST olarak yeniden yapsak daha iyi” denecek noktaya geliyor
Her şeyi kendiniz birleştirmek yerine olgun bir sunucu framework'ü kullanmanın daha iyi olduğunu düşünüyorum
GraphQL dışarıdan hoş görünüyor ama pratikte zaman geçtikçe bakımını sürdürmesi zorlaşan bir teknoloji
Pek çok teknolojide olduğu gibi sonunda tekerlek yine tekerlektir dersini veriyor
GraphQL'nin güzel yanı, şemaya alan eklediğiniz anda tüm istemcilerin bunu hemen sorgulayabilmesi
Böylece FE'nin “şu alanı da ekler misiniz” talepleri ortadan kalkıyor ve iş birliği sadeleşiyor
Ayrıca şema snapshot'ı oluşturup entegrasyon testlerinde değişiklik tespiti yapmak da kolay
REST'ten daha tutarlı geldi ama bu kişisel deneyimim
A'dan E'ye zincirleme istek yapılabildiği için performans düşüşü ya da frontend-veri yapısı bağımlılığı artabiliyor
React de artık framework tabanlı SSR ve server components yaklaşımını benimsiyor
Sonuçta gidişat TypeScript'in istemci ile sunucuyu birleştirmesi yönünde
GraphQL'nin veritabanı yükü ya da verimsiz sorgular sorununu nasıl engellediğini merak ediyorum
Kötü niyetli bir sorgu dahili durumu patlatamaz mı?
REST çok sıkıcı geldiği için GraphQL deniyorum
Sunucu ile istemcinin istek-yanıt üzerinde derleme zamanında uzlaşabilmesi hoşuma gidiyor
Bloglar yalnızca “bu kötü” demekle kalmasa, alternatif teknolojileri de birlikte sunsa keşke
İki teknoloji de istemci-sunucu sözleşmesi sorununu iyi çözüyor