GraphQL ve Mikro Hizmet Mimarisi


176

GraphQL bir Microservice mimarisi içinde kullanmak için en uygun olduğunu anlamaya çalışıyorum.

API Gateway olarak çalışan yalnızca 1 GraphQL şemasına sahip olmak, isteği hedeflenen mikro hizmetlere proxy yapmak ve yanıtlarını zorlamak hakkında bazı tartışmalar vardır. Mikro hizmetler hala iletişim düşüncesi için REST / Thrift protokolünü kullanacaktır.

Başka bir yaklaşım bunun yerine, mikro hizmet başına bir tane birden fazla GraphQL şemasına sahip olmaktır. İsteğin tüm bilgileri + GraphQL sorgusu ile isteği hedeflenen mikro hizmete yönlendiren daha küçük bir API Ağ Geçidi sunucusuna sahip olmak.

1. Yaklaşım

Bir API Ağ Geçidi olarak 1 GraphQL Şemasına sahip olmak, mikro hizmet sözleşmesi giriş / çıkışınızı her değiştirdiğinizde, GraphQL Şemasını API Ağ Geçidi Tarafında buna göre değiştirmemiz gereken bir dezavantaja sahip olacaktır.

2. Yaklaşım

Mikro hizmet başına Çoklu GraphQL Şeması kullanıyorsanız, GraphQL bir şema tanımı uyguladığından ve tüketicinin mikro hizmetten verilen girdi / çıktıya saygı duyması gerektiği için bir şekilde mantıklı olun.

Sorular

  • GraphQL'i mikro hizmet mimarisi tasarımı için uygun buluyor musunuz?

  • Olası bir GraphQL uygulamasıyla bir API Ağ Geçidi'ni nasıl tasarlarsınız?

Yanıtlar:


242

Kesinlikle # 1 yaklaşımı.

Müşterilerinizin birden fazla GraphQL hizmetiyle konuşması (yaklaşım 2'de olduğu gibi) ilk etapta GraphQL'i kullanma amacını tamamen ortadan kaldırır; bu, tek bir gidiş dönüşte tüm uygulama verileriniz üzerinde bir şema sağlamaktır .

Paylaşımlı bir şey mimarisine sahip olmak mikro hizmet perspektifinden makul görünebilir, ancak müşteri tarafı kodunuz için bu mutlak bir kabustur, çünkü mikro hizmetlerinizden birini her değiştirdiğinizde tüm müşterilerinizi güncellemeniz gerekir. Kesinlikle pişman olacaksın.

GraphQL ve mikro hizmetler mükemmel bir seçimdir, çünkü GraphQL, istemcilerden bir mikro hizmet mimarisine sahip olduğunuz gerçeğini gizler. Bir arka uç perspektifinden, her şeyi mikro hizmetlere bölmek istersiniz, ancak bir ön uç perspektifinden, tüm verilerinizin tek bir API'dan gelmesini istersiniz. GraphQL kullanmak, her ikisini de yapmanıza izin veren en iyi yöntemdir. Tüm uygulamanıza tek bir API sağlarken ve farklı hizmetlerden gelen veriler arasında birleşmelere izin verirken arka ucunuzu mikro hizmetlere ayırmanıza olanak tanır.

Mikro hizmetleriniz için REST kullanmak istemiyorsanız, elbette her birinin kendi GraphQL API'sine sahip olabilirsiniz, ancak yine de bir API ağ geçidiniz olmalıdır. İnsanların API ağ geçitlerini kullanmasının nedeni, mikro hizmet desenine iyi uyduğu için değil, istemci uygulamalarından mikro hizmet çağırmayı daha yönetilebilir hale getirmektir.


2
@helfer: Bu gerçekten mantıklı :) teşekkürler. Bu muhteşem cevabın üstünde birkaç sorum var. - GraphQL'in API ağ geçidi olarak kullanılması gerektiğini mi söylüyorsunuz? - Diyelim ki bir REST veya GraphQL uç noktasını açığa çıkaran bir Sipariş Mikro Hizmetim var. Ben bittikten sonra ben tam olarak aynı mikroişlemin ortaya çıkaracağı verileri yansıtmak için ana GraphQL şemasını güncellemek zorunda? Bağımsız olarak uygulanması gereken çoğaltma veya mikro hizmet kültüründen uzaklaşmak gibi bir şey değil mi? Bir mikro hizmette yapılan herhangi bir değişiklik Ana GraphQL Şemasına yansıtılmalı / çoğaltılmalıdır.
Fabrizio Fenoglio

13
@Fabrizio, GraphQL ile güzel olan şey, arka uç REST API'si değişse bile, REST hizmetinin daha önce maruz kaldığı verileri almanın bir yolu olduğu sürece GraphQL şemasının hala aynı kalmasıdır. Daha fazla veri ortaya çıkarırsa, bununla başa çıkmanın standart yolu sadece mevcut şemaya yeni alanlar / türler eklemektir. Facebook'ta GraphQL'i yaratanlar, bana dört yıl içinde şemalarında hiçbir zaman bir değişiklik yapmadıklarını söylediler. Yaptıkları tüm değişiklikler katkıydı, yani yeni istemciler yeni işlevselliği kullanabilirken eski istemciler çalışmaya devam edecekti.
helfer

4
Sağ! :) Bunu yazdığınız için teşekkürler! Seni Medium ve github'da apollo depoları ile takip ediyorum! Makaleleriniz ve yayınlarınız çok değerlidir! :) İyi işlere devam edin! Ayrıca GraphQL + Microservices konulu orta bir makaleyi okumak çok keyifli olacağını düşünüyorum!
Fabrizio Fenoglio

1
Teşekkürler, bunu aklımda tutacağım. Kesinlikle bir noktada GraphQL ve Microservices hakkında yazmayı planlıyoruz, ancak muhtemelen önümüzdeki birkaç hafta içinde değil.
helfer

Seçenek # 2 ile github.com/AEB-labs/graphql-weaver kombinasyonu nasıl olur ?
Mohsen

35

Buradaki # 1 yaklaşımının nasıl ve neden daha iyi çalıştığını anlatan makaleye bakın . Ayrıca bahsettiğim makaleden alınan aşağıdaki resme bakın: resim açıklamasını buraya girin

Her şeyin tek bir uç noktanın arkasına sahip olmasının temel avantajlarından biri, verilerin her bir isteğin kendi hizmeti olduğundan daha etkili bir şekilde yönlendirilebilmesidir. Bu, karmaşıklık ve hizmet sürüngeninde bir azalma olan GraphQL'in sıkça tolere edilen değeri olsa da, ortaya çıkan veri yapısı aynı zamanda veri sahipliğinin son derece iyi tanımlanmasını ve açıkça tanımlanmasını sağlar.

GraphQL'i benimsemenin bir başka yararı da, veri yükleme süreci üzerinde temelde daha fazla kontrol sağlayabilmenizdir. Veri yükleyicileri için işlem kendi uç noktasına girdiğinden, talebi kısmen, tamamen veya uyarılarla onurlandırabilir ve böylece verilerin nasıl aktarıldığını son derece ayrıntılı bir şekilde kontrol edebilirsiniz.

Aşağıdaki makalede, bu iki avantajı diğerleriyle birlikte çok iyi açıklanmaktadır: https://nordicapis.com/7-unique-benefits-of-using-graphql-in-microservices/


HI, noob soruları için özür dilerim, ancak graphQL ağ geçidiniz yeni bir saklama noktası değil mi? Örneğin birden fazla solitik bir sepet hizmetim varsa, benim graphQL ağ geçidimi de kırmaz mıydım? Temelde onun rolü emin değilim, bu ağ geçidi her hizmet için bir sürü çözümleyici içermesi gerekiyordu?
Eric Burel

1
@EricBurel Soru için teşekkürler. Aslında, makaleden anladığım kadarıyla, farklı hizmetlerin tüm şemaları bir GraphQL şeması altında birleştirilmiştir, bu nedenle belirttiğiniz gibi, diğer hizmetler hala kendi veri kümelerinde bulunur. GraphQL ağ geçidi için tek bir hata kaynağı olasılığı ile ilgili olarak, her zaman bir yedekleme planı sağlamak gibi başka seçenekler de vardır. Daha fazla bilgi için lütfen bu makaleyi ( labs.getninjas.com.br/… ) okuyun . Bu yardımcı olur umarım.
Enayat

Merkezi API ağ geçidini ve tek tek hizmetleri nasıl test edersiniz? Entegrasyon mu yapıyorsunuz veya http yanıtıyla alay mı ediyorsunuz?
Jaime Sangcap

7

2 numaralı yaklaşım için, aslında bu benim tercih ettiğim biçimdir, çünkü can sıkıcı API ağ geçidini elle korumaktan çok daha kolaydır. Bu şekilde hizmetlerinizi bağımsız olarak geliştirebilirsiniz. Hayatı daha kolay hale getirin: P

Şemaları bir araya getirmek için bazı harika araçlar var, örneğin graphql-weaver ve apollo'nun graphql-tools , kullanıyorum graphql-weaver, kullanımı kolay ve harika çalışıyor.


GraphQL'i Android'de kullanmak, tüm sorguları içeren bir .graphql dosyası oluşturmam şart mı? Yoksa sadece bu dosya olmadan kodda oluşturabilir miyim?
MauroAlexandro

1
@MauroAlexandro Ben android bir adam değilim, ama farklı dosyalarda sorguları olabilir. Daha çok bir tasarım problemi. IMHO, ilkini tercih ediyorum :)
HFX

5

2019'un ortasından itibaren, 1. Yaklaşım için çözüm şimdi Apollo halkı tarafından " Şema Federasyonu " adını taşıyor (Daha önce bu genellikle GraphQL dikiş olarak adlandırılıyordu). Ayrıca modülleri öneriyorlar ve bunun için.@apollo/federation@apollo/gateway

EKLE: Şema Federasyonu ile şemayı ağ geçidi düzeyinde değiştiremeyeceğinizi lütfen unutmayın. Bu yüzden şemanızda ihtiyacınız olan her bit için ayrı bir hizmetiniz olması gerekir.


bu çözümün ücretsiz sürümde biraz sınırlı olan Apollo Server gerektirdiğini bilmek de geçerlidir (ayda maksimum 25 milyon sorgu)
Marx

0

2019'dan itibaren en iyi yol, apollo ağ geçidi spesifikasyonunu uygulayan mikro-servisler yazmak ve daha sonra bu hizmetleri # 1 yaklaşımını takip eden bir ağ geçidi kullanarak yapıştırmaktır. Geçidini inşa etmenin en hızlı yolu gibi bir liman işçisi resimdir bu eş zamanlı olarak tüm hizmetleri başlatmak için Sonra kullanım liman işçisi-oluşturmadeneyimine:

version: '3'

services:
    service1:
        build: service1
    service2:
        build: service2
    gateway:
        ports:
            - 80:80
        image: xmorse/apollo-federation-gateway
        environment: 
            - CACHE_MAX_AGE=5
            - "FORWARD_HEADERS=Authorization, X-Custom-Header" # default is Authorization, pass '' to reset
            - URL_0=http://service1
            - URL_1=http://service2

0

Bu soruda anlatıldığı gibi, bir düzenleme hizmeti olarak özel bir API ağ geçidi kullanmanın karmaşık kurumsal odaklı uygulamalar için çok anlamlı olabileceğine inanıyorum. GraphQL, en azından sorgulama kadar, bu düzenleme hizmeti için iyi bir teknoloji seçimi olabilir. İlk yaklaşımınızın avantajı (tüm mikro hizmetler için bir şema), birden fazla mikro hizmetten gelen verileri tek bir istekte bir araya getirme yeteneğidir. Durumunuza bağlı olarak bu çok önemli olabilir veya olmayabilir. GUI bir kerede birden fazla mikro hizmetten veri oluşturmayı çağırıyorsa, bu yaklaşım, istemci kodunu basitleştirebilir, böylece tek bir çağrı, Açısal veya Tepki gibi çerçevelerin GUI öğeleriyle veri bağlama için uygun verileri döndürebilir. Bu avantaj mutasyonlar için geçerli değildir.

Dezavantajı, veri API'ları ile düzenleme hizmeti arasındaki sıkı bağlantıdır. Bültenler artık atomik olamaz. Veri API'larınızda geriye dönük değişiklikler yapmaktan kaçınırsanız, bu yalnızca bir sürümü geri alırken karmaşıklık getirebilir. Örneğin, düzenleme hizmetindeki ilgili değişikliklerle iki veri API'sinin yeni sürümlerini yayınlamak üzereyseniz ve bu sürümlerden birini geri almanız gerekiyor ancak diğerini geri almanız gerekiyorsa, yine de üçünü de geri almak zorunda kalacaksınız.

GraphQL ve REST'in bu karşılaştırmasında, GraphQL'in RESTful API'leri kadar verimli olmadığını göreceksiniz, bu nedenle veri API'ları için REST'i GraphQL ile değiştirmenizi önermem.


0

1. soruya Intuit, One Intuit API ekosistemine geçtiğini duyurduğunda birkaç yıl önce GraphQL'in gücünü kabul etti ( https://www.slideshare.net/IntuitDeveloper/building-the-next-generation-of-quickbooks-app-integrations -quickbooks-connect-2017 ). Intuit, yaklaşım 1 ile gitmeyi tercih etti. Bahsettiğiniz dezavantaj aslında geliştiricilerin istemci uygulamalarını kesintiye uğratabilecek kırıcı şema değişiklikleri yapmasını engelliyor.

GraphQL, geliştiricilerin verimliliğini çeşitli şekillerde artırmaya yardımcı oldu.

  1. Bir alan için yeni bir mikro hizmet tasarlarken, mühendisler (arka uç / ön uç / paydaşlar) alan varlıkları için bir şema üzerinde anlaşırlar. Şema onaylandıktan sonra, ana etki alanı şemasıyla (evrensel) birleştirilir ve Ağ Geçidine dağıtılır. Ön uç mühendisleri, arka uç mühendisleri işlevselliği uygularken istemci uygulamalarını bu şema ile kodlamaya başlayabilir. Bir evrensel şemaya sahip olmak, yedekli işlevselliğe sahip iki mikro hizmetin olmadığı anlamına gelir.
  2. GraphQL, istemci uygulamalarının daha basit ve daha hızlı olmasına yardımcı oldu. Birden fazla mikro hizmetten veri almak / verileri güncellemek ister misiniz? Tüm istemci uygulamalarının yapması gereken bir ONE GraphQL isteği ateşlemektir ve API Gateway soyutlama katmanı birden çok kaynaktan (mikro hizmet) veri getirmeye ve harmanlamaya özen gösterir. Apollo ( https://www.apollographql.com/ ) gibi açık kaynaklı çerçeveler GraphQL'in benimsenme hızını artırdı.

  3. Mobil, modern uygulamalar için ilk seçenek olduğundan sıfırdan düşük veri bant genişliği gereksinimleri için tasarım yapmak önemlidir. GraphQL, istemci uygulamalarının yalnızca belirli alanlar için istekte bulunmasına izin vererek yardımcı olur.

Soru 2: API Ağ Geçidi'nde, şemanın hangi kısmının hangi hizmete (sağlayıcıya) ait olduğunu bilen özel bir soyutlama katmanı oluşturduk. Bir sorgu isteği geldiğinde, soyutlama katmanı isteği uygun hizmet (ler) e iletir. Temel alınan hizmet yanıt döndürdüğünde, soyutlama katmanı istenen alanları döndürmekten sorumludur.

Ancak bugün, bir zamanlar bir GraphQL soyutlama katmanı oluşturmaya izin veren birkaç platform var (Apollo sunucusu, graphql-yoga, vb.).


0

GraphQL ve mikro hizmetler ile çalışıyorum

Benim için işe yarayan deneyime dayanarak, işlevsellik / kullanıma bağlı olarak her iki yaklaşımın da birleşimidir, yaklaşım 1'deki gibi asla tek bir ağ geçidim olmayacaktır ... ancak yaklaşım 2 olarak her mikro hizmet için bir grafql nether.

Örneğin, Enayat'ın cevabının görüntüsüne dayanarak, bu durumda yapacağım şey 3 grafik ağ geçidine sahip olmaktır (resimde olduğu gibi 5 değil)

resim açıklamasını buraya girin

  • Uygulama (Ürün, Sepet, Nakliye, Envanter, gerekli / diğer hizmetlere bağlı)

  • Ödeme

  • kullanıcı

Bu şekilde, bir kimlik kartı, kullanıcı kimliği, ödeme kimliği, ödeme durumu gibi bağımlı hizmetlerden ortaya çıkan gerekli / bağlantılı minimum verilerin tasarımına daha fazla dikkat etmeniz gerekir.

Deneyimlerime göre, "Kullanıcı" ağ geçidine sahibim, GraphQL kullanıcı sorguları / mutasyonları, giriş, oturum açma, çıkış yapma, şifre değiştirme, e-posta kurtarma, e-posta onaylama, hesabı silme, profil düzenleme, resim yükleme , vb ... kendi başına bu grafik oldukça büyük !, ayrılmış çünkü sonunda diğer hizmetler / ağ geçitleri sadece userid, isim veya jeton gibi ortaya çıkan bilgileri önemser.

Bu şekilde daha kolay ...

  • Kullanımlarına bağlı olarak farklı ağ geçitleri düğümlerini ölçeklendirin / kapatın. (örneğin, kullanıcılar her zaman profillerini düzenlemeyebilir veya ödemeyebilirler ... ancak ürün arama daha sık kullanılabilir).

  • Bir ağ geçidi olgunlaştığında, büyüdüğünde, kullanımı bilinir veya şemanın kendi ağ geçidine sahip olabilecek bir parçası olan tanımlayabileceğiniz alanda daha fazla uzmanlığa sahip olursanız (... bana git depolarıyla etkileşime giren büyük bir şema ile oldu , Bir havuzla etkileşime giren ağ geçidini ayırdım ve gereken / bağlanan tek bilginin ... klasör yolu ve beklenen şube olduğunu gördüm)

  • Depolarınızın geçmişi daha açıktır ve bir ağ geçidine ve ilgili mikro hizmetlere adanmış bir havuz / geliştirici / ekibiniz olabilir.

GÜNCELLEME:

Ben burada GraphQL, tüm açık kaynak kullanarak tüm arka uçları ile açıklamak aynı yaklaşımı kullanan bir kubernetes küme var, burada ana depo: https://github.com/vicjicaman/microservice-realm

Bu cevabımın bir güncellemesi çünkü cevap / yaklaşımın çalışmakta olan kodun yedeklenmesi ve danışılması / gözden geçirilmesi daha iyi ise daha iyi olduğunu düşünüyorum, umarım bu yardımcı olur.


-3

Mikro hizmet mimarisinin uygun bir tanımı olmadığından, bu stil için belirli bir model yoktur, ancak bunların çoğu birkaç önemli özellik ile gelecektir. Uygulama bütünlüğünü etkilemeden ayrı ayrı ayarlanmış ve dağıtılmıştır. Bu, özel mikro hizmet uygulama geliştirme yoluyla uygulama yeniden dağıtımına gitmeden birkaç hizmeti kolayca değiştirebileceğiniz anlamına gelir .


"Düzgün bir tanım" eksik olsa bile, iyi anlaşılmış bir kavramdır ve soru bağlamında açıkça ayrılmıştır. Bu bir yana, cevabınız soruyu hiç ele almıyor.
Roy Prins

-7

Mikro hizmetler hakkında daha fazla bilgi, GraphQL sunucusuz mimarisinde de mükemmel çalışabilir düşünüyorum. GraphQL kullanmıyorum ama kendi benzer projem var . Bunu birçok işlevi çağıran ve tek bir sonuçta toplayan bir toplayıcı olarak kullanıyorum. Aynı modeli GraphQL için de uygulayabilirsiniz.


2
Üzgünüz, ama bu OP'nin sorusuyla hiç ilgili değil. Soru, GraphQL kullanan iki spesifik yaklaşım hakkındadır. Bu bir yorum olarak daha iyi konulmuş olabilir.
tiomno
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.