gRPC ve REST: En İyi API Protokolüne Başlarken
Yayınlanan: 2022-07-22Günümüzün teknoloji ortamında, çoğu proje API'lerin kullanılmasını gerektirir. API'ler, tek bir karmaşık sistemi temsil edebilen, ancak ayrı makinelerde bulunabilen veya birden çok, uyumsuz ağ veya dil kullanabilen hizmetler arasındaki iletişimi köprüler.
Birçok standart teknoloji, REST, SOAP, GraphQL veya gRPC gibi dağıtılmış sistemlerin hizmetler arası iletişim ihtiyaçlarını karşılar. REST tercih edilen bir yaklaşım olsa da gRPC, yüksek performans, yazılı sözleşmeler ve mükemmel araçlar sunan değerli bir rakiptir.
REST Genel Bakış
Temsili durum aktarımı (REST), bir hizmetin verilerini almanın veya değiştirmenin bir yoludur. Bir REST API, genellikle bir kaynak seçmek için bir URI ve istenen işlemi seçmek için bir HTTP fiili (örneğin, GET, PUT, POST) kullanılarak HTTP protokolü üzerine kuruludur. İstek ve yanıt gövdeleri, işleme özgü verileri içerirken, üstbilgileri meta verileri sağlar. Örneklemek için, bir ürünü REST API aracılığıyla almanın basitleştirilmiş bir örneğine bakalım.
Burada, kimliği 11
olan bir ürün kaynağı talep ediyoruz ve API'yi JSON biçiminde yanıt vermesi için yönlendiriyoruz:
GET /products/11 HTTP/1.1 Accept: application/json
Bu istek göz önüne alındığında, yanıtımız (alakasız başlıklar çıkarılmıştır) şöyle görünebilir:
HTTP/1.1 200 OK Content-Type: application/json { id: 11, name: "Purple Bowtie", sku: "purbow", price: { amount: 100, currencyCode: "USD" } }
JSON insan tarafından okunabilir olsa da, hizmetler arasında kullanıldığında optimal değildir. Özellik adlarına atıfta bulunmanın tekrarlayan doğası - sıkıştırılmış olsa bile - şişirilmiş mesajlara yol açabilir. Bu endişeyi gidermek için bir alternatife bakalım.
gRPC'ye Genel Bakış
gRPC Uzaktan Yordam Çağrısı (gRPC), bir dizi işlevi harici istemcilere sunarak hizmetler arası iletişimi basitleştiren ve yöneten açık kaynaklı, sözleşme tabanlı, platformlar arası bir iletişim protokolüdür.
HTTP/2 üzerine inşa edilen gRPC, çift yönlü akış ve yerleşik Aktarım Katmanı Güvenliği (TLS) gibi özelliklerden yararlanır. gRPC, serileştirilmiş ikili yükler aracılığıyla daha verimli iletişim sağlar. REST'in JSON kullanımına benzer şekilde, yapılandırılmış veri serileştirme mekanizması olarak varsayılan olarak protokol arabelleklerini kullanır.
Ancak JSON'dan farklı olarak, protokol arabellekleri serileştirilmiş bir formattan daha fazlasıdır. Bunlar diğer üç ana bölümü içerir:
-
.proto
dosyalarında bulunan bir sözleşme tanımlama dili (En son protokol arabelleği dili belirtimi olan proto3'ü izleyeceğiz.) - Oluşturulan erişimci işlev kodu
- Dile özgü çalışma zamanı kitaplıkları
Bir hizmette bulunan (bir .proto
dosyasında tanımlanan) uzak işlevler, protokol arabellek dosyasındaki hizmet düğümünün içinde listelenir. Geliştiriciler olarak, protokol arabelleklerinin zengin tip sistemini kullanarak bu işlevleri ve parametrelerini tanımlıyoruz. Bu sistem, giriş ve çıkış mesajlarımızı tanımlamak için çeşitli sayısal ve tarih türlerini, listeleri, sözlükleri ve boş değerleri destekler.
Bu hizmet tanımlarının hem sunucu hem de istemci tarafından kullanılabilir olması gerekir. Ne yazık ki, .proto
dosyasının kendisine doğrudan erişim sağlamanın yanı sıra bu tanımları paylaşmak için varsayılan bir mekanizma yoktur.
Bu örnek .proto
dosyası, bir kimlik verilen bir ürün girişi döndürmek için bir işlevi tanımlar:
Proto3'ün katı bir şekilde yazılması ve alan sıralaması, iletinin seri durumdan çıkarılmasını JSON'u ayrıştırmaktan çok daha az vergilendirme yapar.
REST ile gRPC'yi karşılaştırma
Özetlemek gerekirse, REST ile gRPC'yi karşılaştırırken en önemli noktalar şunlardır:
DİNLENME | gRPC | |
---|---|---|
Çapraz platform | Evet | Evet |
Mesaj Formatı | Özel ancak genellikle JSON veya XML | Protokol arabellekleri |
Mesaj Yük Boyutu | Orta Büyük | Küçük |
İşleme Karmaşıklığı | Daha yüksek (metin ayrıştırma) | Alt (iyi tanımlanmış ikili yapı) |
Tarayıcı Desteği | Evet (yerli) | Evet (gRPC-Web aracılığıyla) |
Daha az katı sözleşmelerin ve yüke sık sık eklemelerin beklendiği durumlarda, JSON ve REST çok uygundur. Sözleşmeler daha statik kalma eğiliminde olduğunda ve hız son derece önemli olduğunda, gRPC genellikle kazanır. Üzerinde çalıştığım çoğu projede gRPC, REST'ten daha hafif ve daha performanslı olduğunu kanıtladı.
gRPC Hizmet Uygulaması
gRPC'yi benimsemenin ne kadar basit olduğunu keşfetmek için basitleştirilmiş bir proje oluşturalım.
API Projesi Oluşturma
Başlamak için Visual Studio 2022 Community Edition'da (VS) bir .NET 6 projesi oluşturacağız. ASP.NET Core gRPC Service şablonunu seçeceğiz ve hem projeyi ( InventoryAPI
kullanacağız) hem de içindeki ilk çözümümüzü ( Inventory
) adlandıracağız.
Şimdi seçelim. çerçevemiz için NET 6.0 (Uzun vadeli destek) seçeneği:
Ürün Hizmetimizi Tanımlama
Projeyi oluşturduğumuza göre, VS, Greeter
adlı örnek bir gRPC prototip tanımlama hizmeti görüntüler. Greeter
çekirdek dosyalarını ihtiyaçlarımıza uyacak şekilde yeniden kullanacağız.
- Sözleşmemizi oluşturmak için,
greet.proto
içeriğini Snippet 1 ile değiştirerek,product.proto
dosyasını yeniden adlandıracağız. - Hizmetimizi oluşturmak için
GreeterService.cs
dosyasının içeriğini Snippet 2 ile değiştirerekProductCatalogService.cs
dosyasını yeniden adlandıracağız.
Hizmet artık sabit kodlanmış bir ürün döndürür. Hizmetin çalışması için, yeni hizmet adına başvurmak için yalnızca Program.cs
hizmet kaydını değiştirmemiz gerekir. Bizim durumumuzda, app.MapGrpcService<GreeterService>();
app.MapGrpcService<ProductCatalogService>();
yeni API'mizi çalıştırılabilir hale getirmek için.
Adil Uyarı: Standart Protokol Testiniz Değil
Denemek için cazip gelsek de, gRPC hizmetimizi uç noktasına yönelik bir tarayıcı aracılığıyla test edemeyiz. Bunu deneseydik, gRPC uç noktalarıyla iletişimin bir gRPC istemcisi aracılığıyla yapılması gerektiğini belirten bir hata mesajı alırdık.
İstemci Oluşturma
Hizmetimizi test etmek için VS'nin temel Konsol Uygulaması şablonunu kullanalım ve API'yi çağırmak için bir gRPC istemcisi oluşturalım. Madeni InventoryApp
olarak adlandırdım.
Uygunluk için, sözleşmemizi paylaşacağımız göreli bir dosya yoluna başvuralım. Referansı .csproj
dosyasına manuel olarak ekleyeceğiz. Ardından yolu güncelleyeceğiz ve Client
modunu ayarlayacağız. Not: Göreceli referanslamayı kullanmadan önce yerel klasör yapınıza aşina olmanızı ve güvenmenizi öneririm.
Hem hizmet hem de istemci proje dosyalarında göründükleri .proto
referansları şunlardır:
Hizmet Proje Dosyası (Müşteri proje dosyasına kopyalanacak kod) | İstemci Proje Dosyası (Yapıştırıp düzenledikten sonra) |
---|---|
|
|
Şimdi, servisimizi aramak için Program.cs
içeriğini değiştireceğiz. Kodumuz bir dizi hedefi gerçekleştirecektir:
- Hizmet uç noktasının konumunu temsil eden bir kanal oluşturun (bağlantı noktası değişebilir, bu nedenle gerçek değer için
launchsettings.json
dosyasına bakın). - İstemci nesnesini oluşturun.
- Basit bir istek oluşturun.
- İsteği gönderin.
Lansman için hazırlanıyor
VS'de kodumuzu test etmek için çözüme sağ tıklayıp Set Startup Projects öğesini seçeceğiz. Çözüm Özellik Sayfaları iletişim kutusunda şunları yaparız:
- Birden çok başlangıç projesinin yanındaki radyo düğmesini seçin ve Eylem açılır menüsünde her iki projeyi de (
InventoryAPI
veInventoryApp
) Başlat olarak ayarlayın. - Tamam'ı tıklayın.
Şimdi VS araç çubuğunda Başlat'a tıklayarak (veya F5 tuşuna basarak) çözümü başlatabiliriz. İki yeni konsol penceresi görüntülenecek: biri bize hizmetin dinlediğini söyleyecek, diğeri bize alınan ürünün ayrıntılarını gösterecek.
gRPC Sözleşme Paylaşımı
Şimdi gRPC istemcisini hizmetimizin tanımına bağlamak için başka bir yöntem kullanalım. Müşteri tarafından en erişilebilir sözleşme paylaşımı çözümü, tanımlarımızı bir URL aracılığıyla kullanılabilir hale getirmektir. Diğer seçenekler ya çok kırılgandır (bir yol üzerinden paylaşılan dosya) ya da daha fazla çaba gerektirir (bir yerel paket aracılığıyla paylaşılan sözleşme). Bir URL üzerinden paylaşım (SOAP ve Swagger/OpenAPI'nin yaptığı gibi) esnektir ve daha az kod gerektirir.
Başlamak için .proto
dosyasını statik içerik olarak kullanılabilir hale getirin. Oluşturma işlemindeki kullanıcı arayüzü "Protobuf Derleyici" olarak ayarlandığından kodumuzu manuel olarak güncelleyeceğiz. Bu değişiklik, derleyiciyi bir web adresinden sunulabilmesi için .proto
dosyasını kopyalamaya yönlendirir. Bu ayar VS UI aracılığıyla değiştirilirse yapı bozulur. O halde ilk adımımız InventoryAPI.csproj
dosyasına Snippet 4'ü eklemektir:
Ardından, .proto
dosyamızı döndürmek üzere bir uç nokta ayarlamak için kodu ProductCatalogService.cs
dosyasının üst kısmındaki Snippet 5'e ekliyoruz:
Ve şimdi, ayrıca ProductCatalogService.cs
dosyasına app.Run()
'dan hemen önce Snippet 6'yı ekliyoruz:
Snippets 4-6 eklendiğinde, .proto
dosyasının içeriği tarayıcıda görünür olmalıdır.
Yeni Bir Test İstemcisi
Şimdi VS'nin Bağımlılık Sihirbazı ile mevcut sunucumuza bağlanacağımız yeni bir konsol istemcisi oluşturmak istiyoruz. Sorun şu ki, bu sihirbaz HTTP/2 konuşmuyor. Bu nedenle sunucumuzu HTTP/1 üzerinden konuşacak şekilde ayarlayıp sunucuyu başlatmamız gerekiyor. Sunucumuz artık .proto
dosyasını kullanıma sunarken, gRPC sihirbazı aracılığıyla sunucumuza bağlanan yeni bir test istemcisi oluşturabiliriz.
- Sunucumuzu HTTP/1 üzerinden konuşacak şekilde değiştirmek için
appsettings.json
JSON dosyamızı düzenleyeceğiz:-
Protocol
alanını (Kestrel.EndpointDefaults.Protocols
yolunda bulunur)Https
okumak için ayarlayın. - Dosya 'yı kaydet.
-
- Yeni istemcimizin bu
proto
bilgilerini okuması için sunucunun çalışıyor olması gerekir. Başlangıçta, hem önceki istemciyi hem de sunucumuzu VS'nin Başlangıç Projelerini Ayarla iletişim kutusundan başlattık. Yalnızca sunucu projesini başlatmak için sunucu çözümünü ayarlayın, ardından çözümü başlatın. (Artık HTTP sürümünü değiştirdiğimiz için eski istemcimiz artık sunucuyla iletişim kuramıyor.) - Ardından, yeni test istemcisini oluşturun. Başka bir VS örneğini başlatın. API Projesi Oluşturma bölümünde ayrıntılı olarak açıklanan adımları tekrarlayacağız, ancak bu sefer Konsol Uygulaması şablonunu seçeceğiz. Projemizi ve çözümümüzü
InventoryAppConnected
adlandıracağız. - Oluşturulan istemci kasası ile gRPC sunucumuza bağlanacağız. VS Solution Explorer'da yeni projeyi genişletin.
- Bağımlılıklar'a sağ tıklayın ve içerik menüsünde Bağlı Hizmetleri Yönet'i seçin.
- Bağlı Hizmetler sekmesinde, Hizmet referansı ekle'yi tıklayın ve gRPC'yi seçin.
- Hizmet Referansı Ekle iletişim kutusunda, URL seçeneğini seçin ve hizmet adresinin
http
sürümünü girin (rastgele oluşturulmuş bağlantı noktası numarasınılaunchsettings.json
almayı unutmayın) . - Kolayca korunabilecek bir hizmet referansı eklemek için Bitir'e tıklayın.
Çalışmanızı bu örnek için örnek koda göre kontrol etmekten çekinmeyin. Başlık altında, VS, ilk test turumuzda kullandığımız aynı istemciyi oluşturduğundan, önceki hizmetten alınan Program.cs
dosyasının içeriğini yeniden kullanabiliriz.
Bir sözleşmeyi değiştirdiğimizde, istemci gRPC tanımımızı güncellenmiş .proto
tanımıyla eşleşecek şekilde değiştirmemiz gerekir. Bunu yapmak için yalnızca VS'nin Bağlı Hizmetlerine erişmemiz ve ilgili hizmet girişini yenilememiz gerekiyor. Artık gRPC projemiz tamamlandı ve hizmetimizi ve müşterimizi senkronize tutmak çok kolay.
Bir Sonraki Proje Adayınız: gRPC
gRPC uygulamamız, gRPC kullanmanın faydalarına ilk elden bir bakış sağlar. REST ve gRPC'nin her birinin, sözleşme türüne bağlı olarak kendi ideal kullanım durumları vardır. Ancak, her iki seçenek de uygun olduğunda, gRPC'yi denemenizi tavsiye ederim; bu, API'lerin geleceğinde sizi eğrinin önüne geçirecektir.