GraphQL ile API geliştirme: adım adım yöntem ve öğrenme yolu
Beceri rehberi

GraphQL ile API geliştirme: adım adım yöntem ve öğrenme yolu

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 6 dk okuma

GraphQL API geliştirmeyi şema tasarımı, çözümleyiciler, yetkilendirme ve performans adımlarıyla öğrenin; sık hataları ve öğrenme yolunu görün.

GraphQL API geliştirmek tam olarak ne demek?

GraphQL, istemcinin hangi alanları istediğini sorguda açıkça yazdığı ve sunucunun yalnızca o alanları döndürdüğü bir API sorgu dilidir. Geliştirici olarak işiniz bir şema yazmak, şemadaki her alanın verisini nereden getireceğinizi tanımlamak ve sunucuyu üretimde güvenli biçimde çalıştırmaktır. Okuma için sorgu (query), yazma için değişiklik (mutation), canlı veri akışı için abonelik (subscription) kullanılır ve hepsi ortak bir uç nokta üzerinden geçer.

REST'te kaynak başına ayrı uç noktalar tasarlanır; istemci ihtiyacından fazla ya da eksik veri alabilir. GraphQL'de sözleşme şemanın kendisidir: istemci ekibi ile sunucu ekibi aynı tip tanımlarına bakarak çalışır. Bu yüzden GraphQL API geliştirmek, kod yazmadan önce bir veri sözleşmesi tasarlamak anlamına gelir. Mobil uygulama, web arayüzü ve iç servisler gibi farklı istemcilerin aynı veriyi farklı biçimlerde istediği durumlarda en çok değer üreten yaklaşım budur.

Şemayı önce tasarlayın: tipler, ilişkiler ve adlandırma

İyi bir GraphQL API'nin omurgası şemadır. Önce alan modelini kâğıt üzerinde çıkarın: hangi nesneler var, aralarındaki ilişkiler neler, hangi alanlar zorunlu? Sonra bunu şema tanım diline (SDL) çevirin. Tipleri veri tabanı tablolarının kopyası olarak değil, istemcinin ihtiyaç duyduğu iş kavramları olarak kurgulayın. Örneğin bir sipariş ekranı için siparişin kalemlerini, müşterisini ve kargo durumunu tek bir sorguda gezebilmek şemanın amacıdır.

Adlandırmada tutarlılık şart: alan adları camelCase, tip adları PascalCase olsun, değişiklikler eylem odaklı adlandırılsın (siparisOlustur gibi). Her değişiklik için ayrı bir girdi tipi (input type) ve ayrı bir sonuç tipi tanımlayın; sonuç tipinde hata bilgisini de taşıyabilirsiniz. Boş değer (null) davranışını bilinçli seçin: zorunlu alanı işaretlerken gerçekten her zaman dolu olacağından emin olun, çünkü sonradan zorunluluğu kaldırmak istemcileri kırabilir.

Sayfalama için baştan bir yöntem belirleyin. İmleç tabanlı (cursor) sayfalama, kayıtlar eklenip silinirken bile tutarlı sonuç verdiği için büyük listelerde tercih edilir. Alan kaldırmak yerine kullanımdan kaldırma (deprecation) işaretini kullanın ve istemcilerin geçişi için zaman tanıyın.

Çözümleyiciler (resolvers) ve veri erişimi

Şemadaki her alanın arkasında bir çözümleyici fonksiyon vardır. Çözümleyici, üst nesneyi, sorgu argümanlarını ve bağlamı (context) alır; veriyi bir veri tabanından, bir başka servisten ya da bir önbellekten getirip döndürür. Bağlam nesnesine oturum açmış kullanıcıyı, veri erişim katmanlarını ve istek bazlı yardımcıları koymak yaygın bir desendir.

En sık karşılaşılan performans tuzağı, iç içe sorgularda her kayıt için ayrı bir veri tabanı çağrısı yapılmasıdır. Bir listedeki tüm siparişlerin müşterisini istediğinizde, her sipariş için ayrı bir müşteri sorgusu çalışabilir. Çözüm, aynı istek içinde gelen anahtarları toplayıp toplu sorguya çeviren gruplama (batching) ve önbellekleme yaklaşımıdır; DataLoader adıyla bilinen desen bunu yapar.

Çözümleyici içine iş kuralı gömmek yerine, iş mantığını ayrı bir servis katmanında tutun. Çözümleyici yalnızca veriyi şemaya uyduran ince bir adaptör olsun. Böylece aynı mantığı test etmek kolaylaşır ve ileride GraphQL dışında bir arayüz eklemeniz gerekirse yeniden yazmak zorunda kalmazsınız.

Kimlik doğrulama, yetkilendirme ve güvenlik

Kimlik doğrulama (kullanıcının kim olduğu) genellikle HTTP katmanında, örneğin bir belirteç (token) doğrulaması ile yapılır ve sonuç bağlama yazılır. Yetkilendirme (kullanıcının neyi görebileceği) ise alan ve nesne düzeyinde çözülmelidir: yalnızca sorgunun girişinde yetki kontrolü yapmak yeterli değildir, çünkü istemci iç içe alanlarla başka kayıtlara ulaşmaya çalışabilir.

GraphQL'e özgü saldırı yüzeyleri vardır. İstemci sınırsız derinlikte iç içe sorgu yazarak sunucuyu yorabilir. Bunun için sorgu derinliği sınırı, sorgu karmaşıklığı puanlaması ve istek başına zaman aşımı kullanın. Üretimde şema keşfi (introspection) özelliğini gereksiz yere herkese açık bırakmayın. Kayıtlı sorgular (persisted queries) kullanarak yalnızca önceden onaylanmış sorguların çalışmasına izin verebilirsiniz; bu hem güvenliği hem de ağ trafiğini iyileştirir.

Hata yönetiminde de dikkatli olun: GraphQL, bir hata olsa bile çoğu zaman başarılı bir HTTP yanıtı döndürür ve hatayı yanıt gövdesindeki errors alanında taşır. Hata mesajlarında iç sistem ayrıntılarını, yığın izlerini ya da veri tabanı ifadelerini istemciye sızdırmayın.

Gerçek zamanlı veri ve büyük sistemlerde federasyon

Abonelikler, sunucunun olay gerçekleştiğinde istemciye veri itmesini sağlar: sohbet mesajı, sipariş durumu, canlı panolar gibi senaryolar. Genellikle WebSocket üzerinden çalışır; bu nedenle bağlantı yaşam döngüsü, yeniden bağlanma ve yetkilendirmenin bağlantı kurulurken ayrıca doğrulanması gerekir. Abonelik sayısı arttıkça ölçeklenme, olay dağıtımı için bir mesaj aracısı kullanmayı gerektirebilir.

Birden çok ekibin kendi servislerini geliştirdiği kurumlarda tek bir devasa şema sürdürmek zorlaşır. Federasyon, her ekibin kendi alt şemasını yönettiği ve bir ağ geçidinin (gateway) bunları birleşik bir şema olarak sunduğu mimaridir. Burada asıl zorluk teknik değil yönetişimdir: ortak tiplerin sahibi kim, kırıcı değişiklik nasıl duyurulur, şema değişiklikleri hangi süreçten geçer? Bu sorulara baştan cevap verilmezse federasyon, merkezi şemadan daha karmaşık bir bağımlılık ağına dönüşür.

Sık yapılan hatalar

  • Veri tabanı şemasını olduğu gibi GraphQL şemasına çevirmek; istemcinin iş ihtiyacı yerine depolama yapısını açığa çıkarır.
  • Gruplama yapmadan iç içe çözümleyiciler yazmak; küçük veride fark edilmeyen yavaşlık, canlıda kendini gösterir.
  • Yetkilendirmeyi yalnızca üst düzey sorguda yapmak.
  • Derinlik ve karmaşıklık sınırı koymamak.
  • Şemayı kullanımdan kaldırma süreci olmadan değiştirmek; istemciler sessizce bozulur.
  • Her şeyi tek bir dev değişikliğe sığdırmak; küçük, amaca özel değişiklikler hem anlaşılır hem de sürümlenebilir.
  • İzleme olmadan canlıya çıkmak. Hangi sorguların yavaş olduğunu, hangi alanların hiç kullanılmadığını ölçmeden şemayı geliştirmek kör uçuştur.

Nasıl öğrenilir: temelden üretime bir yol

Önce GraphQL'in temel kavramlarını ve REST ile farkını öğrenin; sorgu yazmayı bir hazır herkese açık GraphQL oyun alanında deneyin. Ardından küçük bir sunucu kurun: bir şema yazın, birkaç çözümleyici ile bellekteki veriyi servis edin. Sonra gerçek bir veri tabanına bağlayıp ilişkili alanlarla uğraşın ve gruplama sorununu kendi gözlerinizle görün.

Orta aşamada kimlik doğrulama, yetkilendirme, sayfalama ve hata yönetimini ekleyin; test yazın (şema için ve çözümleyiciler için ayrı ayrı). İleri aşamada abonelikler, önbellekleme, kayıtlı sorgular, izleme ve federasyon gelir. Kendi küçük bir projenizi, örneğin bir görev takip uygulamasının API'sini baştan sona geliştirmek, kavramları ezberlemekten çok daha kalıcı öğrenme sağlar.

Bu beceriyi Mindset programlarında nerede çalışırsınız?

Mindset kataloğundaki GraphQL ile API Geliştirme eğitiminin modülleri bu yolu izler: GraphQL temelleri ve REST karşılaştırması, şema tasarımı, çözümleyici geliştirme, kimlik doğrulama ve yetkilendirme, performans ve güvenlik, gerçek zamanlı abonelikler ve üretim ile federasyon.

GraphQL Şema Tasarımı ve Federasyon eğitimi ise şema tasarımı temellerini, ilişkiler ve sayfalamayı, performans optimizasyonunu, güvenliği, federasyon mimarisini ve yönetişim ile gözlemlenebilirliği ayrıntılandırır.

İlgili Mindset programı

GraphQL ile API Geliştirme

Sık sorulanlar

Sık sorulan sorular

GraphQL öğrenmek için önce REST bilmek gerekir mi?

Zorunlu değildir ancak yardımcı olur. HTTP, istek ve yanıt mantığı, JSON ve temel API kavramlarını biliyorsanız GraphQL'in neyi çözdüğünü daha hızlı kavrarsınız. REST bilgisi, hangi sorunlar için GraphQL'in daha uygun olduğuna karar verirken de işe yarar; çünkü her projede GraphQL doğru seçim değildir.

GraphQL API için hangi programlama dili kullanılır?

GraphQL bir dil değil bir belirtimdir; JavaScript ve TypeScript, Python, Java, C#, Go gibi birçok dilde sunucu kütüphaneleri vardır. Genellikle bildiğiniz dilin olgun bir kütüphanesiyle başlamak en doğrusudur. Şema tasarımı ve çözümleyici mantığı dilden bağımsız olarak aynı kalır, bu yüzden öğrendikleriniz taşınabilir.

GraphQL ile REST birlikte kullanılabilir mi?

Evet. Birçok kurum mevcut REST servislerinin önüne bir GraphQL katmanı koyar; çözümleyiciler arka planda bu servisleri çağırır. Böylece istemciler tek bir şema üzerinden çalışırken eski servisler değişmeden kalır. Geçiş kademeli yapılabilir ve riskli bir toptan değişiklik gerekmez.

GraphQL API yavaşlarsa ilk nereye bakılmalı?

Önce hangi sorgunun yavaş olduğunu izleme araçlarıyla bulun. En sık neden, iç içe alanlarda her kayıt için ayrı veri tabanı çağrısı yapılmasıdır; gruplama ve önbellekleme genellikle bunu çözer. Ardından aşırı derin sorguları, gereksiz alan çekimini ve indekssiz veri tabanı sorgularını inceleyin.

Küçük bir proje için GraphQL gerekli mi?

Çoğu zaman gerekmez. Tek bir istemcisi olan, veri ihtiyacı sabit basit bir uygulamada REST daha az kurulum ve bakım yükü getirir. GraphQL; birden çok istemci, değişken veri ihtiyacı ve ilişkili veri gezme gerektiğinde avantaj sağlar. Karar verirken ekibin deneyimini de hesaba katın.

GraphQL API Nasıl Geliştirilir: Şemadan Üretime