- Federasyon hangi sorunu çözer?
- Temel kavramlar: subgraph, supergraph, router, composition
- Varlıklar ve @key: subgraph'lar arasında kimlik paylaşımı
- Referans resolver: varlığı anahtarından geri getirmek
- Bir sorgu federasyonda nasıl yürür?
- Federasyon ne zaman gerekir, ne zaman gerekmez?
- Federasyonda sık yapılan hatalar
- Bu beceriyi Mindset programlarında nerede çalışırsınız?
- Sık sorulan sorular
GraphQL Federation: subgraph'ları supergraph altında birleştirmek
GraphQL Federation ile birden çok servisin tek API'de birleştirilmesi: subgraph, supergraph, router, @key ile varlıklar, referans resolver ve sık hatalar.
Federasyon hangi sorunu çözer?
Servis sayısı arttıkça istemciler farklı API'lerle ayrı ayrı konuşmak zorunda kalır: kullanıcı bilgisi bir servisten, siparişler başka bir servisten, ürünler başka bir servisten alınır. İstemci hem bu servislerin hepsini bilmek hem de sonuçları kendisi birleştirmek durumunda kalır. Tek bir büyük GraphQL şeması yazmak ise bütün ekipleri aynı kod tabanına ve aynı yayın takvimine bağlar.
Apollo Federation bu ikilemin ortasında durur. Birden çok API'yi tek bir GraphQL API'de birleştirir ve bir orkestrasyon katmanı olarak çalışır: istemci tek bir istek gönderir, sistem arka planda birden çok API çağrısını koordine edip tek bir yanıt döner. Her ekip kendi servisinin şemasını geliştirir, ortak şemaya doğrudan katkı verir.
Temel kavramlar: subgraph, supergraph, router, composition
- Subgraph: birleşik grafın parçası olan tek bir GraphQL API. Farklı sunucu uygulamalarıyla ve farklı programlama dilleriyle yazılabilir; yeter ki federasyonla uyumlu olsun.
- Supergraph: subgraph'ların birleşiminden doğan, istemcilerin sorguladığı tek ve birleşik graf.
- Router: istemci isteklerinin giriş noktası. İsteği akıllıca parçalara ayırıp subgraph'lara dağıtır ve birleştirilmiş yanıtı döner. İstemcinin özel bir yapılandırmaya ihtiyacı yoktur; subgraph'ları yalnızca router sorgular.
- Composition (birleştirme): subgraph şemalarının tek supergraph şemasında bir araya getirilmesi. Çelişkili tanımlar bu aşamada yakalanır.
Örneğin bir seyahat uygulamasında kullanıcılar, uçuşlar ve oteller için ayrı API'ler birer subgraph olur; bunların birleşimi supergraph'tır ve istemci tek bir sorguyla hepsinden veri isteyebilir.
Varlıklar ve @key: subgraph'lar arasında kimlik paylaşımı
Federasyonun kalbi varlıktır (entity): bir ya da birden çok benzersiz anahtar alanıyla getirilebilen nesne tipi. Bir tipi varlık yapan şey @key yönergesidir ve her örnek anahtar alanlarıyla benzersiz biçimde tanımlanabilmelidir. Varlığı birden çok subgraph kendi alanlarıyla genişletebilir; her subgraph yalnızca kendi katkı verdiği alanları çözer.
Örnek kurgu: kullanıcı subgraph'ı User tipini tanımlar, sipariş subgraph'ı aynı tipe siparişler alanını ekler:
Kullanıcı subgraph'ında:
type User @key(fields: "id") { id: ID! name: String! }
Sipariş subgraph'ında:
type User @key(fields: "id") { id: ID! orders: [Order!]! }
type Order { id: ID! status: String! }
Her subgraph User'ı id ile tanımlar; en az bir anahtar alanının subgraph'lar arasında ortak olması, birleştirmede tipin tek tipte buluşması için gerekir. Gerekli bildirimler federasyon sürümüne göre değişir; kullandığınız sürümün belgesine bakın. Router, bu bilgiyle istemciye tek bir User tipi sunar ve istemci hangi alanın hangi subgraph'tan geldiğini bilmek zorunda kalmaz.
Referans resolver: varlığı anahtarından geri getirmek
Router bir varlığı başka bir subgraph'tan tamamlamak için ona varlığın temsilini gönderir: anahtar alanları ve __typename. Subgraph'ın bu temsili alıp o subgraph'ın tanımladığı alanları döndüren fonksiyonuna referans resolver (__resolveReference) denir ve varlığın tip resolver haritasında yer alır.
User: { __resolveReference(reference, context) { return context.loaders.user.load(reference.id); }, },
Bu fonksiyon tek sorguda çok sayıda çağrılabilir. Her çağrıda ayrı bir veritabanı sorgusu çalışırsa N+1 sorunu doğar; bu yüzden referans resolver'larda da DataLoader gibi bir gruplama kullanılması önerilir. Anahtar seçerken kuralları da bilin: @key alanları union ya da interface döndüren alanları ve argüman alan alanları içeremez; null olmayan anahtar alanları tercih edilir.
Bir sorgu federasyonda nasıl yürür?
İstemci tek bir sorgu gönderir:
query { user(id: "kullanici-a") { name orders { status } } }
Router sorguyu çözümler ve hangi alanın hangi subgraph'a ait olduğunu bilir. Önce kullanıcı subgraph'ından name alanını ve varlık anahtarını alır, ardından aynı anahtarla sipariş subgraph'ına gidip orders alanını ister ve yanıtları tek JSON'da birleştirir. Bağımsız alanlar paralel çekilebilir; birine ihtiyaç duyan alanlar sırayla.
Bu mekanizmanın pratik sonucu, ağ sıçramalarının sayısının sorgunun yapısına bağlı olmasıdır. Derin ve geniş sorgular router'ı birden çok subgraph'a götürür; bu nedenle subgraph'lar arası sınırları ve en sık kullanılan sorguların yollarını tasarım sırasında düşünmek gerekir.
Federasyon ne zaman gerekir, ne zaman gerekmez?
Federasyon, birden çok ekibin bağımsız servisleri sahiplendiği ve istemcinin yine de tek bir grafla konuşmasını istediğiniz durumlarda anlamlıdır. Her ekip kendi alanlarını geliştirir ve yayınlar, ortak şema bu katkılardan oluşur.
Tek ekipli, tek servisli bir uygulamada federasyon gereksiz karmaşıklık getirir: router, birleştirme süreci ve ek ağ sıçramaları çalıştırmak ve izlemek zorunda kalırsınız. Tek bir şemayı iyi tasarlayabiliyorsanız bu yeterlidir. Mevcut REST servisleriniz varsa onları bir GraphQL katmanıyla sarmak ve ihtiyaç doğdukça federasyona geçmek daha az risklidir.
Federasyonda sık yapılan hatalar
- Alan sahipliğini belirsiz bırakmak: aynı alanı birden çok subgraph çözmeye çalışırsa çelişkiler çıkar. Her alanın tek bir sahibi olmalı.
- Varlık anahtarını sonradan değiştirmek: anahtar, subgraph'ları birbirine bağlar; değişiklik koordinasyon gerektirir.
- Referans resolver'da gruplama yapmamak: N+1 sorunu subgraph'a taşınır.
- Subgraph'ları birbirine sıkı bağlamak: her sorgu bütün servislere gidiyorsa federasyonun getirisi azalır.
- Birleştirme kontrollerini yayın hattına koymamak: kırıcı şema değişikliği üretimde fark edilir.
- Şemayı ekipler arasında belgelememek: hangi alanın hangi ekibe ait olduğu bilinmezse hata anında doğru kişiye ulaşmak zorlaşır.
- Router'ı izlememek: yavaşlık nedeninin hangi subgraph'ta olduğu görünmez olur.
Bu beceriyi Mindset programlarında nerede çalışırsınız?
GraphQL ile API Geliştirme eğitimindeki Üretim ve Federasyon modülü, birden çok servisi tek grafta birleştirmeyi ve üretime almayı çalışır; eğitim, GraphQL sunucusu geliştiren ve ekipler arası API sözleşmesini yöneten arka yüz mühendisleri ile teknik liderler için uygundur. Apollo GraphQL ile İstemci ve Sunucu Geliştirme eğitiminin Performans, Güvenlik ve Federasyon modülü ise aynı konuyu Apollo ekosistemi içinde ele alır.
Kurumsal bağlamda en çok işe yarayan şey, ekipler arası alan sahipliği ve şema değişikliği inceleme kuralının yazılı hale gelmesidir.
İlgili Mindset programı
GraphQL ile API Geliştirme
Sık sorulan sorular
Supergraph ile subgraph arasındaki fark nedir?
Subgraph, tek bir ekibin geliştirdiği bağımsız GraphQL API'dir. Supergraph ise subgraph'ların birleşiminden doğan ve istemcilerin sorguladığı tek birleşik graftır. İstemci yalnızca router üzerinden supergraph ile konuşur, subgraph'lara doğrudan gitmez. Örneğin kullanıcı ve sipariş ekiplerinin ayrı API'leri subgraph, istemcinin gördüğü tek şema supergraph'tır.
@key yönergesi ne işe yarar?
Bir nesne tipini varlık yapar ve onu benzersiz tanımlayan alanları bildirir. Router, aynı varlığı farklı subgraph'larda aynı anahtarla eşleştirip tek tipte birleştirir. Anahtar alanları argüman almamalı, union ya da interface döndürmemeli ve tercihen null olmayan olmalıdır.
Federasyon için mevcut GraphQL servislerimi yeniden yazmam gerekir mi?
Gerekmez; ancak federasyonla uyumlu olmaları ve ortak varlıklar için anahtar tanımlamaları gerekir. Subgraph'lar farklı dillerde ve sunucu uygulamalarında olabilir. Mevcut servislerin şemasına federasyon bildirimleri eklenir, sonra birleştirme yapılır. Geçişi tek seferde yapmak şart değildir; servisleri birer birer subgraph olarak katıp router'ın sonuçlarını eski istemcilerle karşılaştırarak ilerleyebilirsiniz.
Router yavaşlarsa nedeni nasıl bulunur?
Bir sorgunun hangi subgraph'lara gittiğini ve her birinde ne kadar sürdüğünü izleyen bir izleme düzeni kurun. Yavaşlık çoğunlukla belirli bir subgraph'ın referans resolver'ında gruplama eksikliğinden ya da çok sayıda ardışık subgraph sıçramasından kaynaklanır.
İlgili rehberler
İlgili eğitimler
Kategori: Yazılım Geliştirme