API Tasarımı & Web İletişimi 3 dk okuma 9 okunma

gRPC-Web ile Tarayıcıdan gRPC Servislerine Erişim

gRPC-Web, tarayıcı tabanlı uygulamaların (JavaScript, Blazor WebAssembly) gRPC servislerini çağırmasını sağlayan bir protokol adaptasyonudur. Tarayıcılar HTTP/2'nin gerekli düşük seviyeli özelliklerini doğrudan sunmadığı için gRPC-Web, protokolü HTTP/1.1 ve HTTP/2 üzerinde çalışabilir hale getirir. ASP.NET Core'da Grpc.AspNetCore.Web middleware'i ile sunucu tarafında, Grpc.Net.Client.Web paketi ile istemci tarafında (Blazor) uygulanır.

gRPC-Web ile Tarayıcıdan gRPC Servislerine Erişim

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-text iç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.Web paketi, 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.

Tüm yazılar Soru ya da yorumun mu var? Yaz