GraphQL – Veri Erişim Modellerine Farklı Bir Yaklaşım
Yerli yerinde kullanılmayan hiçbir teknoloji bizi uzaya götürmez.
Birkaç hafta önce İngilterede yaşayan bir arkadaşım bir proje getirdi. Global ölçekli düşünülen projede oldukça yoğun kullanıcı ve sağlayıcı aktivitesi planlanmakta. Belirli hizmetleri talep edenlerle bu hizmeti sağlayanları bir araya getiren, her iki tarafında bloglarını tutabileceği yani blog yazabileceği ve puanlamanın olduğu bir web + mobil platform olarak düşünebiliriz.
Oldukça uzun zamandır belki de 10 yıla yakındır MVC şablonu üzerine geliştirmeler ve yazılım tasarımları yapmaktayım. Bu süreçte çoğunlukla 7-8 yıldır backend’i Java ile kurgulayıp frontend’e JavaScript teknolojileri ya koymuşumdur ya da tavsiye etmişimdir. Diyebiliriz ki uzunca bir dönem Rest Servisleri, MVC şablonu içerisinde yaptığımız tasarımlarda backend ile fronted arasında bir iletişim aracı bir köprü olarak kullanmaktayız. Bu süreçte oldukça da faydalı oluyorlar, oldular. Neyse konumuza dönelim.
Gereksinimler doğrultusunda yeni projeyi tasarlarken backend’te Java kullanmamaya herşeyi JavaScript dünyası içerisinde ele almaya karar verdim. Kabaca AngularJS ve NodeJS ekseninde bir mimari oluşturup bu eksende geliştirmeler yapacağız. Geliştirmeler hangi eksende yapılırsa yapılsın işin içinde web + mobil olduğunda veri erişimi için Rest API kullanımı ön plana çıkmaktadır.
Rest API
Diyeceksiniz ki buraya kadar anlattıklarınızdan sanki Rest API de problem var gibi anlıyoruz. Problem değil de geliştirmeye, yükseltmeye ihtiyaç var diyelim. Uzun zamandır Rest API mantığında major bir güncelleme olmadığını görüyoruz.
Yukarıda bahsettiğim projeyi, Rest API tasarlarken ve geliştirirken neler olabileceğine, neleri aşmamız gerekeceğine kısaca bir bakalım. Rest API’ler resource bazlı istek modeli sunarlar. Bu durumda istek modelimiz aşağıdakine benzeyecektir.
1 2 3 4 5 6 7 8 9 10 |
/api/profiles/alp /api/profiles/alp/profile /api/profiles/alp/posts /api/profiles/alp/likes /api/profiles/alp/friends /api/profiles/alp/friends/profilePhotos |
Uygulama yapımıza bağlı olarak bu model şöyle çalışacaktır.
- 1. satırdaki resource tanımı ile alp kullanıcısına ait tüm bilgiler çekilecektir.
- 3. satırdaki resource tanımı ile alp kullanıcısının beğendiği içerikler çekilecektir.
- 5. satırdaki resource tanımı ile alp kullanıcısının arkadaşlarının profil foto’ları çekilecektir.
Bunların hepsi birer rest isteği yani veri erişim isteği olarak sunucuya iletilecektir. Burada en genelden özele doğru bir veri isteği ele alınmıştır. Yani alp kullanıcısına ait tüm bilgiler ya da alp kullanıcısına ait belirli bilgiler sunucudan istenmiştir. Bir de bunların kendi içlerinde {id} gibi belirli değerlere göre filtrelendiğini düşünürsek halimiz yaman ve yazı da baya uzun olur. 😎
Uygulamanın bir sayfasında kullacıya ait sadece profile + posts + likes bilgilerini yayınlayacağımızı düşünelim. Bu durumda iki yöntem kullanabiliriz.
- /api/profile/alp… isteği ile alp kullanıcısına ait tüm bilgileri çekip kullanmayacaklarımızı görmezden gelebiliriz. (Gereksiz veri çekmiş oluyoruz.)
- /api/profiles/alp/profile…+ /api/profiles/alp/posts…+ /api/profiles/alp/likes… istekleri ile alp kullanıcısı için sadece gerekli alanları sunucudan isteyebiliriz. (Bu durumda 3 tane istek oluşturmuş oluyoruz.)
Her iki durumunda kendine göre yarar ve/veya zararları var. Aslında web istemciler bunların bir kısmını hoş bile görebilir. Ancak mobil istemciler için aynını söylemek çok zor.
Bir kullanıcı web‘ten sisteme giriş yapıp istekte bulunduğunda ya çok fazla veri çekecek ya da birden fazla rest isteğine neden olacaktır. Duruma göre bunlardan biri tercih edilir ya da takla atılır. (taklaya girmeyelim) Tercihim: web isteğini işlerken en yüksek performası gösterebilecek rest istekleri yaratmak yönünde olacaktır. Yani kimi zaman hepsini isteyerek kimi zaman da 3-4 isteği ayrı ayrı göndererek isteği çoklu işlemek olacaktır. Bu da birden çok endpoint demek.
Aynı kullanıcı mobil‘den sisteme girdiğinde ise çok daha dikkatli olmam gerekmektedir. Mobil tarafı için veri transferi, şebeke kullanımı ve pil tüketimi vb. büyük önem taşımaktadır. Bu durumda takla atmak da fayda etmeyebilir. Büyük ihtimalle bir gateway api yazıp gerekli / gerksiz veri düzenlemesine / filtrelemesine giderek veriyi en yalın haliyle mobil istemciye göndermeye çalışacağım. Gateway yazmanında kendine münhasır sorunlarına da katlanmak zorunda kalacağım demektir.
Web ya da Mobil farketmeksizin hepimizin içine sinmeyen bazı işler yapacağım. Ya birden fazla Rest Servis requesti oluşturacağım ya da tek bir request ile gereksiz data ‘ları da isteyeceğim. Her ikisinde de içime sinmeyen noktalar olduğundan daha farklı senaryolar üzerinde araştırma yapmaya başladım. Ee malum baya zamandır da developer network’ünde GraphQL konuşulur olunca incelemesem olmazdı.
GraphQL nedir?
İsme bakıp grafiksel birşeyler düşünmemize gerek yok. A query language for your API diye tanımlamışlar kendi sitelerinde. Yani api seviyesinde bir sorgulama dili. Dikkatinizi çekerim veri tabanı seviyesinde değil. API yani uygulama seviyesinde bir sorgulama dili. (Hibernate, nHibernate bir ışık yakabilir.) Hemen belirteyim Facebook tarafından geliştirilmiştir.
Aslında sunucu ve istemci arasında bir interface görevi üstlenerek istemcilerin kendi sorgularını oluşturmasını sağlıyor. Ve yukarıda Rest API ile yapmak zorunda olduğum: gereksiz veri yüklemesini ya da bir den çok endpoint ile yapacağım çoklu rest isteklerinin önüne geçebileceğini söylüyor. “Seni çılgın hadi oradan – Murat Kekilli” demek geldi içimden, dinleyelim.
Görseldeki veri tabanlarını aynı zamanda birer endpoint gibi de düşünebiliriz. Bu nedenle görseli değiştirmedim. Görselin solunda client ve server dataya erişmek için birden çok endpoint kullanırken görselin sağında Client ve Server birer endpoint ile istediğini datayı elde etmektedir.
Yani GraphQL client ile server side uygulama arasında bir noktada durarak client tarafında üretilen isteklerin doğru şekilde işlenmesini sağlamaktadır. Bu aynı veri tabanında çalışan birden çok endpoint ‘i devre dışı bırakmak şeklinde de olabilir. Yine bu birden çok endpoint ‘i birden çok veri tabanında da devre dışı bırakmak şeklinde de olabilir.
Kısacası GraphQL ile tasarlanan sistemlerde
- Client tek bir query ile ihtiyacı olan veriyi elde edebilmektedir.
- İstenen verinin derlenmesi, toplanması ve filtrelenmesi gibi işlemleri üzerine almaktadır.
- Kodlamadaki kalite artışını söylemeye bile gerek yok sanırım.
Bu şartları sağlayan ya da sağlayabilen bir sistem bizleri büyük iş yükü ve veri transferi derdinden kurtaracaktır düşüncesindeyim.
GraphQL Servers
- Relay : Facebook tarafından geliştirilmiş en yetenekli GraphQL server. Tek kötü tarafı react zorlaması
- Apollo Stack : Relaydan sonra en gelişmiş sunucu ve tüm node.js ekosisteminde çalışabiliyor.
Bu serverlar ve özellikleri çoğaltılabilir. Ben en güçlü olan iki tanesini buraya yazdım.
GraphQL’in popülerliği arttıkça Rest API öldü yazanları gördüm. Siz Rest API öldü dersiniz cenazenize Rest API gelir. Bkz. Java için yıllardır aynı şarkı söylenir. Evet, GraphQL mevcut durumu ile birçok soruna çare olmaktadır. Ancak Rest API’yi de gömmeyelim. Gün gelir lazım olur.
“Yerli yerinde kullanılmayan hiçbir teknoloji bizi uzaya götürmez”, demiştik. Evet, bir bisiklet bizi belki uzaya götürmez ancak her koşulda bir yerden bir başka yere götürecektir. Yani hiç bir araç tamamen gereksiz değildir. Yapmamız gereken gideceğimiz yere göre araç seçmektir.
Ben rest api ‘yi gömmeden GraphQL macerasına atılacağım ya siz?
İnşaallah, en kısa zamanda projedeki gerçekleştirim sonuçlarıbı ve birkaç çalışan örneği sizlerle paylaşmayı planlıyorum.
Kaynaklar:
So what’s this GraphQL thing I keep hearing about?