İçeriğe atla
Ayhan Sipahi Ayhan Sipahi

gRPC, Protobuf ve Gateway’inizin İzin Verdiği Wire Format

Private REST API gRPC’yi yapısal olarak taşıyamaz ve gRPC konuşan her AWS yüzeyi Lambda hedeflerini dışlar. gRPC’den neyi tutmalı, neyi bırakmalı.

Bu katmanı alternatiflerin karşısında seçtiniz. Sıradaki soru onun neyi taşıyabildiği ve 101. bölümdeki katmanı gören, service mesh dünyasından gelen herkes bunu bir dakika içinde soruyor: neden gRPC değil? Orada doğu-batı trafiğinin varsayılan taşıyıcısı gRPC ve soru da yerinde.

Cevap bir tercih meselesi değil, yapısal. Private REST API istekleri HTTP/1.1’e düşürüyor, gRPC ise HTTP/2 framing üzerinde taşınıyor. Dahası, gRPC konuşan her AWS yüzeyi Lambda fonksiyonlarını hedef olmaktan çıkarıyor; yani gateway değiştirmek sizi kurtarmıyor. Ama takımların gRPC’den asıl istediği şey bütün bunlardan sağ çıkıyor, çünkü istenen şey hiçbir zaman taşıma katmanı değildi. Şemaydı.

gRPC neden masada değil

Service mesh dünyasından gelen herkes bunu bir dakika içinde soruyor. Orada doğu-batı trafiğinin varsayılan taşıyıcısı gRPC’dir: tipli sözleşme, üretilmiş istemciler, streaming, tek bağlantı üzerinden çok sayıda çağrı. Yerinde bir soru ve cevabı bir tercih meselesi değil. Yapısal bir engel var.

gRPC HTTP/2 ister, private REST API ise onu konuşmayı reddeder. gRPC wire protokolünün adı zaten gRPC over HTTP2 ve şöyle diyor: “serves as a detailed description for an implementation of gRPC carried over HTTP2 framing” (gRPC over HTTP/2). Bu bağımlılık kozmetik değil. Bir çağrı HTTP/2 trailer’larıyla sonlanır ve spec bu konuda net: “Status must be sent in Trailers even if the status code is OK.” HTTP/1.1’in bunun karşılığı yok. Spec, bunu beceremeyen aracıları tespit etmek için bir de mekanizma koyuyor ve TE: trailers başlığını şöyle tanımlıyor: “Used to detect incompatible proxies”.

Private bir API istekleri HTTP/1.1’e düşürür; 103. bölüm bunu kaydeder: “If you make a request using HTTP/2 protocol, the request is enforced to use HTTP/1.1 protocol.” Tek cümle meseleyi kapatıyor. Bu serinin önerdiği taşıma katmanı, gRPC’nin üzerinde taşındığı protokolü düşürüp atıyor. AWS hiçbir yerde “API Gateway gRPC desteklemez” diye bir cümle yayımlamıyor, o yüzden öyle bir cümle aramayın. Kanıt, o düşürme satırının kendisi.

Lattice sizi kurtarmıyor ve insanların yanıldığı yer tam olarak burası. Sezgisel hamle, gRPC’yi gerçekten destekleyen VPC Lattice’e uzanmak oluyor. Plan yapmadan önce kısıtı okuyun. Lattice, gRPC protocol version için “The only supported target types are INSTANCE and IP” diyor ve ardından açıkça ekliyor: “You can’t use Lambda functions as targets” (Lattice target group’ları). ALB de kendi gRPC target group’ları için aynı dışlamayı taşıyor (ALB target group’ları). HTTP/2 protocol version’da da hedef tipi kısıtı ikisinde aynı.

İçselleştirilmeye değer örüntü şu: gRPC konuşan her AWS yüzeyi, Lambda fonksiyonlarını hedef olmaktan çıkarıyor. Lattice, gRPC’nin kilidini açan bir gateway değişimi değil. Doğu-batı yönünde gRPC gerekiyorsa değiştirdiğiniz şey gateway’iniz değil, compute’unuz olur.

Altta yatan sebep Lambda’nın çalışma modeli. Lambda fonksiyonu bir sunucu değildir. Bir portu dinleyen süreç yoktur ve bağlantıyı açık tutacak bir şey de yoktur: “Lambda freezes the execution environment when the runtime and each extension have completed and there are no pending events” (execution environment). gRPC’nin uğruna sevildiği ne varsa, kalıcı bağlantı, çoğullanmış stream’ler, çift yönlü streaming, hepsi o bağlantıyı tutan uzun ömürlü bir sunucuyu varsayar. Donmuş, istek-cevap modelli bir ortam bunu veremez. Lambda’nın response streaming’i ise bambaşka bir mekanizmadır ve bunların hiçbirini vermez: gRPC framing yok, trailer yok, client streaming yok.

İddiayı tam yerinden kurun, çünkü dikkatli okur bunu test edecek. gRPC’yi sonlandıramayan şey Lambda fonksiyonlarıdır. Lambda MicroVM’ler bunu yapabiliyor ve networking dokümantasyonları desteklenen gelen protokoller arasında gRPC’yi sayıyor. Bu bir karşı örnek değil. MicroVM size bir portta uzun ömürlü bir sunucu süreci veriyor; yani gRPC’nin ihtiyaç duyduğu şeklin ta kendisini. Varlığı kuralı bozmuyor, doğruluyor.

Sözleşmeyi koruyun, taşımayı bırakın. gRPC’yi soyduğunuzda çoğu takımın istediği şey tipli sözleşme ve üretilmiş istemcilerdir; iki Lambda arasında çift yönlü streaming değil. Bunların hepsini koruyabilirsiniz. .proto şemaları yazın, istemcileri üretin ve private API üzerinden sıradan bir HTTP/1.1 POST ile protobuf veya JSON gönderin. Connect protokolü tam bu şekil için tasarlanmış ve bunu açıkça söylüyor: “Bidirectional streaming requires HTTP/2, but the other RPC types also support HTTP/1.1. The protocol doesn’t use HTTP trailers at all, so it works with any networking infrastructure” (Connect protokolü). Vazgeçtiğiniz şey streaming ve çoğullama. Lambda’nın çalışma modeli bunları zaten hiçbir zaman veremeyecekti; yani kayıp kulağa geldiğinden küçük.

Karar kuralı kısa. Doğu-batı gRPC, o servisi bir ALB’nin ya da IP hedefli Lattice’in arkasındaki uzun ömürlü bir container’a taşımak için gerekçedir. Gateway değiştirmek için gerekçe değildir ve private bir API Gateway’e ikna yoluyla yaptırılabilecek bir şey de değildir.

Tablo eksik kalmasın diye bir kayıt. Haziran 2026’da çıkan Lambda MicroVM’ler, her MicroVM’e HTTP/2, gRPC ve WebSocket konuşan bir HTTPS URL’i veriyor. AWS bunları doğu-batı taşıması olarak değil, güvenilmeyen ya da AI üretimi kod için izole sandbox’lar olarak konumluyor. Yani AWS’in iç trafiği gRPC’ye yönlendirdiğini okumayın buradan. Kuralın doğrulanmasını okuyun: protokol, tam olarak uzun ömürlü bir sunucu süreci geldiği anda geliyor.

Wire format sözleşme demek değil

Bir takıma neden gRPC istediğini sorun; dürüst cevap neredeyse hiçbir zaman HTTP/2 çoğullaması olmaz. İstenen şey şema disiplinidir: payload için tek bir doğruluk kaynağı, her dilde üretilmiş istemciler ve biri bir alanın tipini değiştirdiğinde build’i düşüren bir CI kapısı. Bu bir sözleşme meselesidir. gRPC onu bir taşıma katmanıyla paketleyip veriyor ve Lambda’nın alamadığı kısım tam da o taşıma katmanı. İyi haber şu: paket açılabiliyor.

Protobuf bir kodlamadır, taşıma değil (Protocol Buffers). Binary protobuf’u sıradan bir HTTP/1.1 POST ile gönderebilirsiniz. Bu bir kurnazlık değil, spesifikasyonda yazıyor. Connect protokolü “does not depend on framing details specific to a particular HTTP version” diyor ve kendi referansında düz bir POST /service/Method HTTP/1.1 isteği gösteriyor: Content-Type: application/proto ve sıkıştırılmamış binary protobuf gövde (Connect protokolü). AWS de kendi evinde aynı fikirde: Smithy RPC v2 CBOR protokolü http: ["h2", "http/1.1"] bildiriyor ve payload’ları application/cbor olarak taşıyor (Smithy RPC v2 CBOR). Binary payload HTTP/2 gerektirmez. Gerektiren şey yalnızca gRPC’nin framing’idir.

Ama API Gateway byte’ları vergilendiriyor ve tuzak burada. REST API varsayılan olarak metin öncelikli: payload’ları UTF-8 metin olarak işler. İçerik tipini binaryMediaTypes listesine kaydetmediğiniz bir route’a protobuf gövde gönderirseniz gateway byte’larınızı UTF-8 metin sanıp bozar. Tipi düzgün kaydettiğinizde ise ikinci kuralla tanışırsınız: “When converting a binary payload to a text string, API Gateway always applies a base64 encoding on the binary data” (binary media type’lar). Lambda proxy event’i, JSON bir body string’i ve bir isBase64Encoded bayrağı taşır; yani binary gövde base64 kodlanmış olarak varır ve protobuf onu görmeden önce handler’ınız çözer.

Base64, her üç byte için dört karakter demek. Bu, tanımı gereği sabit üçte bir şişme, üstüne çağrılan tarafta ödediğiniz bir decode. Protobuf yine de genelde eşdeğer JSON’dan küçük kalır, çünkü çok daha aşağıdan başlar; ama platform, binary formatın kazandığının büyük kısmını sessizce geri alıyor. Bu taşıma katmanında “payload küçülsün diye protobuf’a geçtik” cümlesi kulağa geldiğinden zayıf bir gerekçedir.

O hâlde sözleşmeyi alın, byte’ları bırakın. Şemayı yazın, istemcileri üretin ve kırıcı değişiklikleri CI’da kapıya takın. buf breaking, bir şemayı önceki sürümüyle karşılaştırır ve mevcut istemcileri kıracak bir değişiklikte hata verir; örneğin bir alanın tipinin int32’den string’e dönmesini raporlar (Buf). Bunların hiçbiri gRPC, HTTP/2 ya da binary gövde istemiyor. Zaten istediğiniz kısım buydu. Private API üzerinden JSON gönderin, şemayı doğruluk kaynağı olarak tutun ve binary’ye ancak ölçülmüş bir payload base64 vergisini ödemeye değdiriyorsa uzanın.

Burada JSON makul varsayılan olmaya devam ediyor ve bu tembellikten değil. JSON platformun kendi para birimi: proxy event’i zaten JSON ve CloudWatch Logs, X-Ray ile konsoldan test invoke, hepsi onu bir çözücüye ihtiyaç duymadan okuyor. Sözleşme katmanında ise HTTP ve JSON API’ler için standart OpenAPI, güncel sürümü 3.2.0 (OpenAPI Specification).

Endüstrinin yönelimini adıyla anmakta fayda var, çünkü kanıtı AWS’in kendisi. Yönelim şu: şema-önce sözleşmeler, değiştirilebilir wire format. Smithy, “a language for defining services and SDKs” olarak tanımlanıyor ve AWS bu IDL’in “widely used within Amazon and AWS for over a decade” olduğunu söylüyor (Smithy). Sözleşme IDL’dir; protokol ise değiştirebileceğiniz bir trait. Ve AWS onu değiştiriyor: CloudWatch ve GameLift gibi servis modelleri artık eski protokollerinin yanında smithy.protocols#rpcv2Cbor bildiriyor. CBOR’un kendisi de tam bir Internet Standard, STD 94 (RFC 8949). Bu, bitmiş bir geçiş değil; servis servis, dil dil süren bir göç. Ders temiz şekilde genelleşiyor: AWS kendi SDK’larının altındaki wire format’ı değiştirebiliyor, çünkü sözleşme hiçbir zaman wire format değildi. Doğu-batı katmanınızı da böyle kurun; format, sonradan yeniden ele alabileceğiniz bir karar olarak kalsın.

Sık yapılan hatalar

  1. Compute Lambda fonksiyonlarında kalırken gRPC uğruna VPC Lattice’e geçiş planlamak. Lattice’in gRPC hedef tipleri yalnızca INSTANCE ve IP ve bunu açıkça söylüyor: “You can’t use Lambda functions as targets.”
  2. İçerik tipini binaryMediaTypes listesine hiç kaydetmediğiniz bir route’a protobuf gövde göndermek. Gateway byte’ları UTF-8 metin sanıp bozar ve size bunu kimse söylemez.
  3. Bu taşıma katmanında payload küçülsün diye protobuf’a geçmek. Base64 sabit üçte biri geri ekler, üstüne çağrılan tarafta bir decode. Byte’lar için değil, sözleşme için geçin.

Sözleşme yerine oturdu ve wire format kararı verildi. 103. bölüm katmanı CDK ile ayağa kaldırıyor.

Kaynaklar

  • gRPC over HTTP/2 - Tel protokolü. gRPC HTTP/2 framing üzerinde taşınır, status trailer’larda döner ve TE: trailers uyumsuz proxy’leri tespit etmek için vardır.
  • VPC Lattice target groups - gRPC protocol version için “The only supported target types are INSTANCE and IP” ve “You can’t use Lambda functions as targets”. Lattice’in Lambda için bir gRPC kaçış kapısı olmamasının sebebi.
  • ALB target groups - Load balancer tarafındaki birebir aynı dışlama: gRPC target group’ları yalnızca instance ve ip destekler ve “You can’t use Lambda functions as targets.”
  • Lambda execution environment - “Lambda freezes the execution environment when the runtime and each extension have completed and there are no pending events.” gRPC’nin çoğullayacağı bir bağlantının neden var olmadığı.
  • The Connect protocol - Sıradan HTTP/1.1 POST üzerinde protobuf, spesifikasyonda: protokol “does not depend on framing details specific to a particular HTTP version” ve trailer kullanmıyor.
  • Protocol Buffers - “A language-neutral, platform-neutral extensible mechanism for serializing structured data” ve sürümler arası uyumu sağlayan alan numarası kuralları.
  • Binary media types in API Gateway - REST API varsayılan olarak UTF-8 metindir ve “API Gateway always applies a base64 encoding on the binary data”. Bu taşıma katmanından geçen her protobuf veya CBOR payload’ına binen üçte birlik vergi.
  • Smithy - AWS’in IDL’i; “widely used within Amazon and AWS for over a decade”. Sözleşme modeldir, wire protokolü ise değiştirilebilir bir trait.
  • Smithy RPC v2 CBOR - AWS’in kendi binary protokolü; http: ["h2", "http/1.1"] bildiriyor. Binary payload’ların HTTP/2 gerektirmediğinin kanıtı.
  • RFC 8949: CBOR - Tam bir Internet Standard, STD 94. AWS’in kendi SDK’larını doğru taşıdığı, standards-track binary format.
  • Buf: breaking change detection - Bir alanın tipi değiştiğinde build’i düşüren CI kapısı. Takımların gRPC’den asıl istediği kısım ve ne gRPC ne de HTTP/2 gerektiriyor.
  • OpenAPI Specification - HTTP ve JSON API’ler için standart sözleşme dili, güncel sürümü 3.2.0.

Serverless İç Servis Katmanı: Kurmadığınız, Oluşturduğunuz Mesh

Çok takımlı bir serverless yapıda service mesh benzeri doğu-batı iletişimini private API Gateway üzerine kurmak. Kimlik, şifreleme, wire format'lar, maliyet ve endüstrinin gerçekte nereye gittiği.

İlerleme 2/7 yazı tamamlandı

İlgili yazılar