gRPC-Web ile Tarayıcıdan gRPC Servislerine Erişim
gRPC, HTTP/2 üzerinde yüksek performanslı, tip güvenli bir RPC framework'üdür. Ancak tarayıcılar, gRPC'nin ihtiyaç duyduğu HTTP/2'nin düşük seviyeli özelliklerine (trailers, framing) JavaScript API'leri üzerinden erişim izni vermez. Bu nedenle tarayıcıdan doğrudan bir gRPC servisini çağırmak mümkün değildir . gRPC-Web, bu boşluğu doldurmak için tasarlanmış bir protokol adaptasyonudur.
1. gRPC-Web Nasıl Çalışır?
gRPC-Web, tarayıcı sınırlamalarını aşmak için gRPC protokolünde bazı değişiklikler yapar :
-
HTTP/2 Bağımlılığını Kaldırır: gRPC-Web, HTTP/1.1 ve HTTP/2 üzerinde çalışabilir; HTTP/2'ye özel framing gerektirmez.
-
Trailers'ı Gövdeye Taşır: Normal gRPC'de durum bilgisi HTTP trailers'da taşınırken, gRPC-Web'de bu bilgi yanıt gövdesinin sonuna bir "trailer frame" olarak eklenir.
-
Metin Tabanlı Akış Desteği: Base64 kodlu
application/grpc-web-textiçerik tipi ile bazı tarayıcı kısıtlamaları aşılır.
İki Temel Uygulama Yaklaşımı:
-
Envoy Proxy ile Çeviri: Tarayıcıdan gelen gRPC-Web çağrısı Envoy tarafından alınır, HTTP/2 gRPC'ye çevrilir ve arkasındaki servise iletilir .
-
ASP.NET Core Middleware ile Doğrudan Destek:
Grpc.AspNetCore.Webpaketi, ayrı bir proxy'ye ihtiyaç duymadan gRPC-Web çağrılarını kabul etmenizi sağlar .
2. ASP.NET Core'da Sunucu Tarafı Yapılandırması
Mevcut bir gRPC servisini tarayıcıdan çağrılabilir hale getirmek için:
Adım 1: Grpc.AspNetCore.Web paketini ekleyin.
Adım 2: Program.cs dosyasında middleware'i yapılandırın :
csharp
var builder = WebApplication.CreateBuilder(args); builder.Services.AddGrpc(); var app = builder.Build(); app.UseGrpcWeb(); // Routing sonrası, endpoint'lerden önce app.MapGrpcService<GreeterService>().EnableGrpcWeb();
Alternatif olarak, tüm servisler için varsayılan olarak etkinleştirmek isterseniz:
csharp
app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
app.MapGrpcService<GreeterService>();
3. CORS Yapılandırması (Kritik)
Tarayıcı güvenliği, farklı bir alan adından gelen istekleri engeller. gRPC-Web çağrıları için CORS yapılandırılmalı ve gRPC'ye özel başlıklar WithExposedHeaders ile açıkça belirtilmelidir :
csharp
builder.Services.AddCors(o => o.AddPolicy("AllowAll", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.WithExposedHeaders("Grpc-Status", "Grpc-Message",
"Grpc-Encoding", "Grpc-Accept-Encoding");
}));
app.UseCors(); // Routing sonrası, endpoint'lerden önce
Grpc-Status ve Grpc-Message gibi başlıklar açığa çıkarılmazsa, tarayıcı bu başlıkları okuyamaz ve hata durumları düzgün işlenemez.
4. .NET İstemci (Blazor WebAssembly) Kullanımı
Blazor WebAssembly uygulamaları tarayıcıda çalıştığı için aynı HTTP kısıtlamalarına tabidir. .NET istemcisi ile gRPC-Web çağrısı yapmak için Grpc.Net.Client.Web paketi kullanılır :
csharp
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
HttpHandler = new GrpcWebHandler(new HttpClientHandler())
});
var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(new HelloRequest { Name = "Tarayıcı" });
GrpcWebHandler Seçenekleri:
-
GrpcWebMode.GrpcWeb: Kodlama yok (varsayılan). -
GrpcWebMode.GrpcWebText: Base64 kodlu içerik. Tarayıcıda server streaming için bu mod gereklidir .
DI ile Kullanım (Önerilen):
csharp
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(options =>
{
options.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() => new GrpcWebHandler(new HttpClientHandler()));
Kritik Uyarı: Blazor WebAssembly'de senkron metotlar (SayHello) uygulamayı kilitleyebilir; her zaman asenkron metotları (SayHelloAsync) kullanın .
5. Sınırlamalar
| Özellik | Destek Durumu |
|---|---|
| Unary RPC | ✅ Desteklenir |
| Server Streaming | ✅ Desteklenir (GrpcWebText modunda) |
| Client Streaming | ❌ Desteklenmez |
| Bidirectional Streaming | ❌ Desteklenmez |
Client streaming ve bidirectional streaming, tarayıcı API'lerinin doğrudan desteklemediği özelliklerdir. Ayrıca Azure App Service ve IIS üzerinde barındırılan ASP.NET Core gRPC servislerinde de bu iki streaming türü desteklenmez .
6. Ne Zaman gRPC-Web, Ne Zaman Alternatif?
gRPC-Web Kullanın:
-
Zaten bir gRPC servis altyapınız varsa ve tarayıcıdan bu servislere erişmek istiyorsanız.
-
Blazor WebAssembly uygulaması geliştiriyorsanız.
-
Tip güvenliği ve Protobuf tabanlı serileştirme avantajlarından yararlanmak istiyorsanız.
Alternatifleri Değerlendirin:
-
REST/JSON: Geniş tarayıcı uyumluluğu ve basitlik öncelikliyse.
-
SignalR / WebSocket: Tarayıcıda bidirectional streaming gerekiyorsa.
-
gRPC JSON Transcoding: Mevcut gRPC servislerinizi RESTful JSON API olarak sunmak istiyorsanız (ASP.NET Core 7+ ile desteklenir) .
Sonuç
gRPC-Web, mevcut gRPC servislerinizi tarayıcı uygulamalarına açmanın pratik bir yoludur. ASP.NET Core'da Grpc.AspNetCore.Web middleware'i ile sunucu tarafında, Grpc.Net.Client.Web paketi ile Blazor WebAssembly istemcisinde kolayca uygulanır. Ancak client streaming ve bidirectional streaming desteğinin olmadığını ve CORS yapılandırmasının zorunlu olduğunu unutmamak gerekir. Unutmayın: gRPC-Web, gRPC'nin tüm gücünü tarayıcıya taşımaz; ancak unary ve server streaming çağrıları için olgun ve tip güvenli bir köprü sunar.