1 puan yazan GN⁺ 2025-01-24 | 1 yorum | WhatsApp'ta paylaş
  • API tasarımının başlangıç noktası RPC ile REST arasındaki farktır; üç yöntem de HTTP ile ilişkilendirilebilir, ancak çağrı oluşturma ve istemciyi yapılandırma modelleri farklıdır
  • REST, sunucunun sağladığı URL’leri izleyen bir hipertext modelidir; bu nedenle istemcinin URL biçimlerini birleştirdiği OpenAPI tarzı API’lerden ayrılır
  • OpenAPI, URL yol şablonları ve HTTP metotlarıyla işleri tanımlar; pratik ve yaygın olarak kullanılır, ancak REST’ten çok HTTP’ye eşlenmiş bir RPC modeline daha yakındır
  • gRPC, IDL, kod üretimi, ikili payload ve HTTP/2 bağlantı yönetimi aracılığıyla RPC API’lerini doğrudan tanımlar ve HTTP ayrıntılarını gizler
  • gRPC, her iki tarafta da özel yazılım gerektirir ve proxy ile güçlendirme, eşzamanlı güncellemeleri önleme ve kısmi güncellemelerde kısıtları vardır; bu yüzden özellikle dahili API’ler veya Cloud Endpoints gibi bir dönüştürme katmanı kullanılabildiğinde uygundur

HTTP tabanlı API’lere bakmak için üç model

  • HTTP’yi API taşıma katmanı olarak kullanan başlıca yaklaşımlar REST, OpenAPI ve gRPC olarak ayrılır
  • Pek çok açık API’nin ve özel dağıtık API’nin HTTP kullanmasının nedenlerinden biri, kurumların 80 ve 443 numaralı portlardaki HTTP trafiğinin güvenlik konularına aşina olmasıdır
  • Üç yöntem de HTTP ile ilişkilendirilebilir, ancak neyin adres olarak alındığı ve istemcinin çağrıları nasıl oluşturduğu farklıdır

REST: URL’leri birleştirmek değil, izlemek

  • REST’te istemci, sunucunun ilettiği URL’yi olduğu gibi kullanır; URL biçimini API tanımının bir parçası olarak anlamaz veya birleştirmez
  • Tarayıcı, mevcut sayfayı, yer imlerini ve kullanıcının girdiği URL’leri izler; en fazla URL’den HTTP istek bilgilerini çıkarır veya göreli URL’leri mutlak URL’ye dönüştürür
  • REST API’nin özü, kaynaklar arasındaki referansları diğer kaynakların URL’leriyle ifade eden hipertext/hipermedya kullanımıdır
  • REST yaklaşımında tüm tanımlayıcılar URL olarak alınıp verilir
    • POST /accountsaccount_URL
    • POST /subscriptions içine account_URL iletilir → subscription_URL
    • GET {account_URL} → hesap veri ağacını döndürür
  • REST’in avantajları web’in kendi kararlılığına, tutarlılığına ve evrenselliğine yakındır; HTTP/REST’in varlık odaklı modeli API’yi daha basit ve daha düzenli hâle getirebilir

OpenAPI: HTTP’ye doğrudan eşlenmiş RPC’ye yakın

  • OpenAPI, paths altında URL yol şablonlarını tanımlar ve yol ile HTTP metodunun birleşimine işlem(operation) der
  • /pets/{petId} gibi bir yol, istemcinin {petId} değerini bilmesini ve bunu URL şablonuna yerleştirerek HTTP isteği oluşturmasını gerektirir
  • Bu yaklaşımda istemcinin URL biçimini ayrıntılı şekilde bilmesi gerekir; bu yüzden REST’in hipertext modelinin tersidir
  • OpenAPI’nin yaygın kullanılmasının nedeni açıktır
    • Geleneksel RPC modeline benzediği için programcılara tanıdıktır
    • RPC kavramlarını HTTP isteklerine doğrudan eşlemek mümkündür
  • Açık API’lerde standart HTTP teknolojileriyle neredeyse tüm dillerden ve ortamlardan erişilebilmesi büyük bir avantajdır
  • Buna karşılık URL yolu, HTTP metodu ve parametre eşlemelerinin tasarlanması gerektiği için hem API sağlayıcılarının hem de tüketicilerinin öğrenmesi gereken ayrıntılar artar

gRPC: HTTP/2’yi gizleyen RPC uygulama teknolojisi

  • gRPC, HTTP/2’yi taşıma katmanı olarak kullanır, ancak API tasarımcısına ve istemci-sunucu koduna HTTP ayrıntılarını göstermez
  • gRPC istemcisinin çağrı akışı basittir
    • Çağrılacak prosedüre karar verir
    • Kullanılacak parametre değerlerini hesaplar
    • Parametreleri kod üretilmiş stub’a geçirerek çağrıyı yapar
  • gRPC, uzak prosedürleri interface description language temelinde tanımlar; OpenAPI’de olduğu gibi URL yolu, parametre ve HTTP metodu eşlemelerini birlikte ifade etmeye gerek yoktur
  • Kod üretimi, framework’ler ve kütüphaneler aracılığıyla istemci kütüphaneleri ve sunucu uygulamaları oluşturmak daha kolay olabilir
  • İkili payload ve HTTP/2 bağlantı yönetiminden yararlanarak performans avantajları sağlar; aynı teknolojileri gRPC olmadan doğrudan kullanmak da mümkündür, ancak daha fazla teknik öğrenim gerektirir

OpenAPI yerine gRPC’yi değerlendirirken

  • OpenAPI ile API tasarlarken işlemleri ve parametreleri URL yolları ile HTTP metotlarının birleşimi olarak ifade etmek gerekir; seçenekler çok olduğundan bu zorlayıcı olabilir
  • RPC tarzı modeli kullanmaya devam edilecekse gRPC, HTTP’ye yönelik özel eşleme tasarlama yükünü azaltır
  • gRPC ve OpenAPI’nin temel API modelleri benzerdir, ancak HTTP’yi dışa açma biçimleri farklıdır
    • OpenAPI, HTTP taşıma ayrıntılarını istemciye gösterir ve tasarımcı eşlemeyi kontrol eder
    • gRPC, önceden tanımlanmış eşlemeler ve üretilmiş kod aracılığıyla HTTP ayrıntılarını gizler
  • OpenAPI’nin büyük avantajı, istemcinin standart HTTP araçlarını ve teknolojilerini olduğu gibi kullanabilmesidir; pek çok API tasarımcısı için bu avantaj ek tasarım maliyetini haklı çıkarır

RPC’ye varlık odaklı modeli eklemek

  • gRPC veya OpenAPI kullanılsa bile RPC metotlarını varlık merkezli biçimde sınırlandırmak REST’in bazı avantajlarını sağlayabilir
  • Prosedür tanımlarından başlamak yerine önce kaynak tiplerini tanımlayıp ardından her tipe standart varlık işlemlerini karşılık getiren bir yaklaşımdır
  • Temel işlemler Create, Retrieve, Update, Delete ve List’tir; genellikle CRUD plus List olarak görülebilir
  • Gerektiğinde ek işlemler tanımlanabilir, ancak varlık odaklı kavramlarla prosedür odaklı kavramlar karıştığında bazı avantajlar zayıflayabilir
  • Prosedürleri varlık tiplerine göre gruplamak, nesne yönelimli dillerin temel fikirlerinden biridir

gRPC’nin kısıtları ve dikkat edilmesi gerekenler

  • gRPC, hem istemci hem de sunucu tarafında özel yazılım gerektirir; üretilmiş kodun iki tarafın derleme süreçlerine de entegre edilmesi gerekir
  • JavaScript veya Python gibi geliştirme ortamlarında derleme süreci çok az olan dinamik dil kullanıcıları için bu gereksinim yük olabilir
  • Google Cloud Endpoints, gRPC API’lerine HTTP ve JSON üzerinden erişim sağlayarak istemci seçeneklerini geri kazandırır; ancak tüm kullanıcılar bunu kullanamaz veya eşdeğer işlevi kuramaz
  • REST API’de metaveri olmadan bile tamamını tarayan bir bot yapmak kolaydır; buna karşılık gRPC veya OpenAPI gibi RPC tarzı API’lerde her varlık tipi için farklı API’ler ve metaveri ya da özel yazılım gerekir
  • HTTP API’lerinde çoğu zaman Apigee Edge gibi API yönetim araçları ve proxy’ler aracılığıyla güvenlik özellikleri, giriş doğrulama, veri biçimi eşlemeleri, header ve gövde düzenlemeleri eklenir; ancak gRPC’de bu tür proxy güçlendirmeleri çok daha zor olabilir
  • gRPC, eşzamanlı güncellemelerden kaynaklanan veri kaybını önlemeye yönelik standart bir mekanizma tanımlamaz
    • HTTP bunun için Etag ve If-Match header’larını sunar
  • gRPC kısmi güncelleme mekanizması da tanımlamaz
    • HTTP’de PATCH vardır; JSON için standart olarak JSON merge patch ve JSON patch bulunur
    • JSON merge patch daha basittir, ancak dizi güncellemeleri gibi tüm durumları ele alamaz
    • JSON patch daha fazla durumu ele alır, ancak kullanımı daha karmaşıktır

Seçim ölçütleri

  • REST hipertext modelini zaten tasarlamayı biliyorsanız veya öğrenmeye istekliyseniz, kararlılık, tutarlılık ve evrenselliği hedefleyen iyi bir seçenek olabilir
  • OpenAPI, yalnızca standart HTTP teknolojileriyle erişilebilen API’ler oluşturabilir; ancak RPC kavramlarını HTTP’ye eşleme tasarım seçenekleri arttığı için tasarım, uygulama ve öğrenme zorlaşabilir
  • OpenAPI düşünülen bir API için gRPC’yi de birlikte değerlendirmek anlamlıdır. İki yöntemin temel API modelleri karşılaştırılabilir düzeydedir ve gRPC, HTTP eşlemesini doğrudan oluşturma ihtiyacını azaltır
  • gRPC şu koşullarda özellikle caziptir
    • Cloud Endpoints gibi ürünlerle istemcinin gRPC teknolojisini mutlaka benimsemesinin gerekmediği durumlarda
    • Sunucu ve tüm istemcilerin teknoloji seçimlerini kontrol edebildiğiniz dahili API’lerde
  • OpenAPI veya REST yerine gRPC benimsenirken, Apigee Edge gibi API yönetim araçlarına dayalı proxy’lerle API davranışını güçlendirme veya düzeltme fırsatlarının çok daha sınırlı olabileceği dikkate alınmalıdır

1 yorum

 
GN⁺ 2025-01-24
Hacker News yorumları
  • Zamanı geri alabilseydim gRPC'yi en başta öğrenmemi engellemek isteyecek kadar böyle düşünüyorum.
    Başta vizyonuna kapılmıştım ama birkaç yıl geçince çok fazla baş ağrısı çıkardığını gördüm. İç yapıyı gizlediği iddiası da neredeyse şaka gibi; 10 isteğin 1'inde yaşanan hatanın nedenini bulmak için debug loglarını boca edip, adları bile muğlak 10-20 timeout/yeniden deneme ayarını kurcalamak zorunda kalıyorsunuz.
    Maven eklentileri, tuhaf deadline exceeded hataları, HTTP/2'den hoşlanmayan load balancer'lar, güvenlik duvarları yüzünden sonunda standart API kullanmak zorunda kalınan durumlar, zayıf dokümantasyon ve gözlemlenebilirlik tarafında işe yarar hata mesajları elde etmeye çalışmak; hepsi zaman yedi.

    • gRPC'nin sorunu protokol ya da protobuf'un kendisinden çok, en azından Java tarafındaki araç zincirinin berbat olması.
      Üretilen kodun geliştirici deneyimi kötü; client stub'ları final somut sınıflar olduğu için testlerde mock'lamak zor, sunucu implementasyonu da interface yerine somut bir sınıftan miras almak zorunda.
      Sunucu metotları asenkron imzaya sahip olduğundan @Transactional gibi AOP tabanlı davranışları bozuyor; exception desteği de yok. Değişmez değer sınıfları güzel ama hepsini builder ile oluşturmak gerekiyor.
      Sonuçta SOA'da gRPC kullanmak istiyorsanız, gRPC gürültüsünü gizleyip test edilebilir, temiz kod elde etmek için çok fazla tesisat kodu yazmanız gerekiyor. Thrift'in RPC derleyicisinde de benzer sorunlara ek başka sorunlar var.
    • Bu sorunlar gRPC/protobuf spesifikasyonunun kendisinden çok belirli implementasyonların sorunlarına daha yakın görünüyor.
      Güncel .NET ve C# ile gRPC deneyimi oldukça iyi; Microsoft da WCF gibi eski RPC teknolojilerini sonlandırıp gRPC'ye odaklandı.
    • En yoğun kullandığım proje Java'ydı; protoc tarafından üretilen binding çıktısını doğrulamak, doğrudan serileştirme yapmaktan daha laf kalabalığına açık ve hataya yatkındı.
      Wire protokolü type-safe değil; type tag'ler var ama aynı tag birden çok veri tipi için yeniden kullanılıyor. zig-zag tamsayı kodlaması da yavaş.
      Bir RPC kütüphanesi olarak berbat; bizzat deneyimlediklerim arasında ondan daha kötüsü sadece FlatBuffers'dı.
    • Maven'dan bahsettiğinize göre Java kullanıyor gibisiniz; son yaklaşık 8 yıldır Go ile programlama yapan biri olarak gRPC deneyimim epey farklı.
      Bu farkın Java'dan mı yoksa gRPC teknolojisinin kendisinden mi kaynaklandığını merak ediyorum.
    • Go+Dart stack'inde gRPC'yi birkaç yıldır kullanıyorum ama bu tür sorunlar hiç yaşamadım.
      Java+gRPC'ye özgü bir sorun olup olmadığını merak ediyorum.
  • Uzun süredir API geliştiriyorum; hem gRPC hem de HTTP/REST kullandım ve OpenAPI tanımından Go istemcisi ve sunucusu üreten kütüphane https://github.com/oapi-codegen/oapi-codegen’i de yayımladım.
    Yazıda OpenAPI ile REST’i ayırma biçimine katılmak zor. OpenAPI, HTTP API’lerinin davranışını belgelemenin bir yoludur; ister RESTful API olsun ister tamamen keyfi bir API, ikisini de ifade edebilir. Araçların yorumlayabileceği şekilde API’yi açıklayan bir şema dili olması bakımından, gRPC protokolünü belirleyen Protocol Buffer dosyalarıyla kavramsal olarak benzerdir.
    gRPC, proto alıp gönderen bir RPC mekanizmasıdır; Google protobuf’u açık kaynak yaparken şirket içi RPC katmanı Stubby’yi açmamıştı ve gRPC, Stubby kadar iyi değildir. Yine de aktarım verimliliği yüksektir ve genişletmesi de görece kolaydır.
    Ancak gRPC, yaygın HTTP kütüphaneleri kadar sağlam bir ekosistem değildir; logging veya kimlik doğrulama gibi middleware’leri çoğu zaman kendiniz uygulamanız gerekir. Farklı dillerde uygulanmış servisler arasındaki RPC’de bu özellikle böyledir.
    Bana göre gRPC’nin asıl sorunu proto dosyalarıdır. Tüm istemcilerin sunucuyla uyumlu bir .proto dosyasıyla derlenmiş olması gerektiği için keşfedilebilir bir protokol değildir. HTTP API’leri, OpenAPI açıklaması olmadan da curl veya kendi yazdığınız kodla çağrılabilir; bu da bağı daha gevşek kılar ve bu yüzden geliştirme ile debug etmeyi kolaylaştırır.

    • Bu blogun “OpenAPI” dediği şey ile gerçek anlamda REST arasında bir ayrım var. Yine de pratikte gerçekten REST API yapan yer neredeyse yok; çoğu OpenAPI tarzı yaklaşımı kullanıyor.
      Roy Fielding’in 2000 tarihli doktora tezinde tanımladığı REST’te, kök URL’ye GET yapıldığında 200 OK yanıtının içinde bağlantılar olur ve bu bağlantılar izlenerek API’nin sunduğu tüm kaynaklar gezilebilmeliydi. Hiyerarşik yapı serbestti ama her şeye bağlantı ağacının bir yerinden erişilebilmesi gerekiyordu; amaç keşfedilebilirlik sağlamaktı.
      Son 20 yılda çalıştığım yerlerin neredeyse tamamı POST resource_name/resource_id/sub_resource/sub_resource_id/mutation_type veya şirketin idempotency işleme biçimine göre PUT resource_name/resource_id/sub_resource/sub_resource_id kullanıyordu; istemci de Swagger/OpenAPI gibi yapısal bilgilere dayanarak sihirli URL’ler oluşturuyordu.
      Bu yüzden titiz kişiler, Fielding’in REST tanımını uygulamadığı anlamında pratikteki bu tarza “REST” değil “RESTful” demeyi tercih eder.
    • OpenAPI ile REST’in ayrıldığı kısım bana da kafa karıştırıcı geldi. Yazıda REST denilen şey HATEOAS’a daha yakın görünüyor.
      İç/dış istemcileri olan oldukça büyük API’leri yöneten biri olarak, OpenAPI tanımından kod üretme akışını da anlamakta zorlanıyorum. Üretilen stub’ları doldurup API tanımını tekrar tekrar iyileştirdiğinizde araç yeniden yeni stub’lar üretiyor; elle birleştirme gerekiyor ve API büyüdükçe ilgili değişiklikleri bulmak zorlaşıyor.
      Bu yüzden go/ast vb. kullanarak koddan OpenAPI tanımı üreten bir canavar yaptım. Mükemmel değil ama hem Echo hem Gin’de çalışan %95’lik bir çözüm; yeni endpoint gerektiğinde istek/yanıt struct’larını ve boş handler’ı oluşturup dokümanı üreterek frontend geliştiricisine göndermek şeklinde hızlı ilerlemek mümkün.
      Çoğu geliştiricinin API’yi OpenAPI ile nasıl ifade edeceğini düşünmesine gerek kalmıyor ve dokümantasyon da kodla her zaman uyumlu oluyor.
    • Günümüzde keşif için gRPC reflection var: https://grpc.io/docs/guides/reflection/
    • OpenAPI tanımlarını kullanarak üretilmiş tiplerle birlikte SQL benzeri bir sorgu söz dizimi de geliştiriyorum. Böylece herhangi bir üçüncü taraf API aynı hissiyatla kullanılabiliyor.
      Apipe.new(GitHun) |> from("search/repositories") |> eq(:language, "elixir") |> order_by(:updated) |> limit(1) |> execute()
      Kullanılabilir gRPC fonksiyonlarını veya üçüncü taraf API’nin RESTful tuhaflıklarını bilmek gerekmiyor; yerleşik dokümantasyon ve tip erişimi de korunuyor.
      https://github.com/cpursley/apipe
      JS/TS projelerine Supabase gibi eklenebilmesi için bir TypeScript adapter katmanı da düşünüyorum.
      const { data, error } = await apipe.from('search/repositories').eq('language', 'elixir').order_by('updated').limit(1)
      Bu çağrı bir Elixir proxy üzerinden geçirilip asenkron işleme veya hız sınırlama gibi ağır işleri ona yaptırabilir.
    • gRPC’nin keşfedilebilir bir protokol olmadığı sözü tamamen doğru değil.
      Protobuf’un JSON serileştirmesine dayanarak OpenAPI açıklaması oluşturup Swagger ile sunabilirsiniz; gRPC’nin kendisi de yerleşik reflection ve bunu kullanan grpcurl yardımcı aracını sağlar.
  • FAANG şirketlerinden birkaçında çalışmış biri olarak Thrift/gRPC iç servis yönlendirmesi için gerçekten çok kullanışlı
    Ancak bu karmaşıklığın önemli bir kısmı; kütüphaneleri, servis keşif katmanını, yönlendirmeyi vb. yapan ekipler tarafından yönetiliyor. RPC protokolü kullanınca, sıradan JSON/REST servisleriyle yapılması zor olan ölçekte ve hızda bunlar mümkün hale geliyor
    Fiillerin REST API’dan dışarı sızmadığı bir durum da hiç görmedim; bir backend service mesh kurmam ya da iki yerel servisi bir ağ akışıyla bağlamam gerekse her zaman gRPC’yi seçerdim
    Ama müşteriye veya web’e açık kullanım için gRPC’yi asla kullanmam. RPC güçlüdür çünkü birçok kararı sabitler ve “tek bir yöntemi” dayatır. Buna karşılık, farklı teknoloji yığınlarındaki çeşitli istemcilerin servisi kullanması gerekiyorsa REST çok daha iyidir

    • Açık API’lerde yapmam ama özel API’lerde basitçe POST /api/doThingy adresine JSON gövdesi göndermek gibi ele alıyorum
      En temel HTTP istemcisi olan herkesin katılabileceği kolay bir RPC; tüm işletim sistemleri ve tarayıcılarda iyi çalışıyor. URL yoluna mı, sorgu parametresine mi, gövdeye mi koyacağınla boğuşmaya da gerek yok
      Buf veya Connect gibi işleri daha az zahmetli hale getirmeye çalışan sunucu ailelerini kullanırsan gRPC’de de HTTP üzerinden JSON’u memnuniyetle kabul ediyorlar
    • Web olmayan istemci/sunucu uygulamalarında durumun nasıl olduğunu merak ediyorum
      REST’ten çok daha gerçek zamanlı iletişim gerektiren çevrimiçi oyunlar veya MMO’lar aklıma geliyor; ama bugünlerde soket bağlantısının üzerine bir şeyler mi bindiriliyor, pek emin değilim
    • İç servis yönlendirmesinde Thrift/gRPC bir nimet ise, bunun neyle karşılaştırıldığında böyle olduğunu merak ediyorum
      Başka neleri denediklerini de bilmek isterim
    • “Fiillerin dışarı sızması” ne demek, merak ediyorum
  • Çift yönlü streaming yapmıyorsanız gRPC’nin çoğunlukla zaman kaybı olduğunu düşünüyorum
    Çalışma zamanı geçişli bağımlılık cehennemi, araç zinciri cehennemi var; Google içinde her uygulamayı yöneten ekipler bile temel işlevlerin nasıl çalışması gerektiği konusunda felsefi olarak uzlaşamıyor gibi görünüyor
    Kendi dilimi kullanmayan ekiplere, özellikle Go/Python/Java olmayan ya da onlar olsa bile eski sürümlerini kullanan ekiplere bir gRPC API açmayı; ticari hazır ürünlerle entegre etmeyi; ya da tarayıcıya açmayı denerseniz hepsinde bir ara katman gerekiyor

    • Birden fazla şirket ve ekipte gRPC kullandım; her şirketin mühendis sayısı kabaca 100–500 civarındaydı ve bağımlılık ya da araç zinciri sorunu yaşamadım
      gRPC genel olarak sorunsuzdu
    • Doğrudan tarayıcıya açılmaması gerektiğini düşünüyorum. Bu gRPC’nin iyi olduğu alan değil; JSON’a çeviren özel bir katman yapmak daha iyi
      Backend servislerinin birbiriyle iletişiminde REST kullanmak da performans gereksinimi varsa pek anlamlı değil; arada sırada küçük veri alan çağrılar dışında insan tarafından okunabilir bir protokol/API kullanmak için güçlü bir neden yok
    • Tarayıcıya bir gRPC API açmaya çalışırken “JSON’a uygun” bir arayüz yapmadığım için sorguya çekildiğimi hatırlıyorum
      oneof alt tiplerinden, o anda alanı olmayan bir tipi döndürünce otomatik dönüşüm sonucu { "id": "id", "sub_type_two": { } } gibi çıkıyordu
      İşlevsel olarak çalışıyor ve ileride alan eklense bile o kod çalışmaya devam ediyor. Ama web dünyasında yanıt tipini boş nesneyle göstermek tuhaf; protobuf yazarken bu tür sorunlar pek görünmeyebilir
    • Çift yönlü streaming, “ölçekli” işletmek istediğiniz şeyler için genelde kötü bir fikir
    • Protobuf streaming için uygun değil
      Akla gelebilecek neredeyse tüm ikili protokollerle karşılaştırıldığında streaming karşıtı sayılır
  • Şirkette gRPC kullandığım tek deneyim, başka bir kıdemli geliştiricinin “performans lazım” diyerek dayattığı bir projeydi
    Sonunda frontend’in tüketebilmesi gerektiği için JSON API de yaptık; o geliştirici dışında gRPC deneyimi olan kimse yoktu. Aslında o geliştirici de gRPC Python hızlı başlangıç kılavuzunun ötesine geçmemişti ve hata düzeltmelerine de yardım etmedi
    Proje pek çok nedenle berbat durumdaydı ve gRPC’yi haklı çıkaracak ölçeğe de hiç ulaşmadı
    Yine de kişisel olarak biraz kullandığım gRPC hoşuma gitti; çok daha fazla çalışma ve düşünme gerektirdiğini hissettiriyor. Bu, JSON API’lerle çok daha fazla deneyimim olduğu için de olabilir

    • Bu, gRPC’nin kendisinden çok, benimsemeden önce tarayıcıyla uyumlu olmadığını bile bilmeyen “kıdemli” geliştiriciye yönelik bir eleştiri gibi görünüyor
  • ConnectRPC https://connectrpc.com/ kullanmayı keyifli buluyorum
    gRPC’nin sorunlu kısımlarının çoğunu düzeltiyor; Safari WebTransport’u kabul ederse ConnectRPC’nin daha iyi streaming geliştirebileceğini umuyorum
    Başta https://buf.build bana fazla gelmişti, ama üçüncü taraf proto dosyalarını tek tek indirmeden getirebilme özelliği belirleyici oldu
    deps:
    - buf.build/landeed/protopatch
    - buf.build/googleapis/googleapis
    Otomatik SDK üretimi de büyük bir avantaj. Eskiden yaklaşık 9 dil için SDK’ları otomatik ürettiğini övecektim; ama son bir iki gün içinde güncellenmiş ve artık 16 dilin yanı sıra OpenAPI ve başka yeni özellikler de görünüyor
    Ben de gRPC streaming’in sahte vaadine kapıldım ve bu belge deneyimimle tam olarak örtüşüyor: https://connectrpc.com/docs/go/streaming/

    • ReactNative’de çalıştırmak için ConnectRPC streaming’e yönelik küçük bir WebSocket tabanlı sarmalayıcı yaptım
      Bu sayede tarayıcıda da çift yönlü streaming kullanılabiliyor
    • Yine de Protocol Buffers kullanıyor ve gRPC’de yaşadığım sorunların çoğu tam da oradan geliyor
    • Safari’nin WebTransport desteğiyle ilgili yeni bir haber var mı, merak ediyorum
  • Google, sektörün tamamına psikolojik savaş açmış gibi, herkesi iç servis iletişiminde gRPC kullanmaya zorlamış hissi veriyor
    gRPC’nin geliştirici deneyimi REST’e göre epey kötü
    Birine bir endpoint’i çağırmak için basit tek bir komut veremiyorsunuz; standartlaşmamış ek araçlar gerekiyor. Üstelik üretilen istemci tarafı kodu, hangi dilde olursa olsun nadiren görülecek kadar çirkin bir yığın

    • Backend açısından gRPC’nin geliştirici deneyiminin REST’ten kötü olduğu sözüne kesinlikle katılmıyorum
      Tek bir protokol değişikliğiyle hangi alt tüketicileri güncellemek ve yeniden dağıtmak gerektiğini statik olarak bilebiliyorsunuz; bu da haftalar sürecek işi bir saatlik değişikliğe indirebilir
      Aldığınız ve gönderdiğiniz mesajların anında doğrulandığını da biliyorsunuz; ayrıca daha sonra geri yüklemek üzere ucuza saklayabiliyorsunuz
      proto ile son derece okunabilir API dokümantasyonu elde ediyorsunuz; kodun ya da iş mantığının içinde bulanıklaşmıyor. Sürüm yönetimi ve kullanım dışı bırakma anlamları da yerleşik; map dışında daha zengin veri yapıları da destekleniyor
      Karşılaştırınca JSON backend’de şişkin ve eski görünüyor
    • gRPC önemli açılardan bir standarttır
      Veri tiplerini ve fonksiyon imzalarını yazınca, gerçek bir fonksiyon gibi çağırabileceğiniz bir şey elde edersiniz; serileştirme/ters serileştirme boilerplate’i yerine iş mantığına odaklanabilirsiniz
      Thrift de aynı şekilde her şeyi elde yapmaya göre çok daha iyi; GraphQL’in ise daha da iyi olduğunu düşünüyorum
    • Birkaç şirkette zorunlu olarak kullandım ama %99’u gereksiz teknik borç yatırımıydı
      Go’da bile yeniden üretilebilirlik ve paylaşılan proto sürüm yönetimini çözmek zahmetli; her yeni dil eklendiğinde daha da kötüleşiyor
      Yine de tüm startup’lar 100 mikroservise ve gRPC’ye ihtiyaçları olduğunu düşünüyor gibi
  • “API bir REST API ise istemcinin URL biçimini anlaması gerekmez; bu biçim istemciye verilen API spesifikasyonunun bir parçası değildir” cümlesi Roy Fielding’in REST tanımıyla örtüşüyor
    Fielding, bir REST API’ye başlangıç URI’si ve standartlaştırılmış medya tipi kümesi dışında ön bilgi olmadan girilmesi gerektiğini; bundan sonra tüm uygulama durum geçişlerinin, sunucunun sunduğu seçenekler arasından istemcinin seçim yapmasıyla gerçekleşmesi gerektiğini yazmıştı
    https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypert...
    Zaten çok tartışılmış bir konu ama gerçek RESTful bir sistemde istemciye verilen “API spesifikasyonu”nun yalnızca ilk giriş noktası URI/URL’si olması gerektiği hâlâ ilginç

    • Kendini betimleyen REST fikri artık HATEOAS olarak daha iyi biliniyor
      Şahsen bunun şişkin olduğunu ve gerçek bir problemi çözmediğini düşünüyorum
      https://en.m.wikipedia.org/wiki/HATEOAS
    • Yalnızca ilk giriş noktasını yayımlayan bir REST API için API istemcisinin nasıl yazılacağını merak ediyorum
      Özellikle istemcinin üzerinde işlem yapabileceği kaynakları ya da istek/yanıt modellerini nasıl keşfetmesi gerektiğini bilmiyorum
    • Gerçek RESTful bir sistemde istemciye verilen API spesifikasyonunun yalnızca ilk giriş noktası URI/URL’si olması gerektiğine tamamen katılmıyorum
      Yapılandırma açısından böyle olabilir; ama API spesifikasyonu URL’den çok daha fazlası olmalı ve sistemin kullandığı medya tiplerini ayrıntılı açıklamalı. Yani HTTP istek/yanıt gövdelerinin açıklaması çoğunlukla gerekli
      Bağlantıda da “REST API, açıklama çabasının neredeyse tamamını kaynakları temsil eden ve uygulama durumunu yönlendiren medya tipi tanımlarına harcamalıdır” deniyor
      Sonuçta yalnızca application/json döndürmüyor; belirli bir +json gibi bir şey döndürüyor ve çoğu zaman bu genel JSON değil, uygulamanın anlaması gereken iş verilerini içeriyor
      Popüler tartışmalarda odak yalnızca başlangıç URL’sine kayıyor; Fielding’in söylediği “medya tipini açıklayın” kısmındaki işlerin çoğu atlanıyor. Bu yüzden “tek URL yeter” sözünü duyan birinin “spesifikasyonun geri kalanı nerede?” diye sorması doğal
    • İkisi de aynı şeye katılıyor. Buradaki “URL biçimi” kelimenin tam anlamıyla URL’nin biçimi; kaynak biçimi değil
      Ben de yine REST’i anlamamış bir blog yazarı mı diye yazıya tıkladım ama yazar en azından temel kavramları biliyor gibi
      gRPC’yi de seviyorum ve ticari projelerde oldukça çekici; ama kişisel ya da idealist bir proje olsaydı REST’in daha iyi olduğunu düşünüyorum
    • İyi bir fikrin popüler olduktan sonra, insanların o fikri yanlış anlayarak yaymaya devam etmesinin tipik bir örneği
  • Veri merkezi içinde gRPC kullanmayı sevmiyorum
    Performans gerekçesiyle seçiliyor ama gRPC’nin yüksek performanslı olduğunu söylemek zor; herkese açık istemci kalitesi de özellikle C++/Java çekirdek uygulamalarının dışında çok düşük. Örneğin Node.js uygulaması böyle
    protobuf’un API spesifikasyonu olarak kullanılmasına karşı değilim; ancak TCP üzerinde bir framing protokolüyle birlikte kullanılabilmeli. Ne var ki bu tür RPC’de belirgin biçimde baskın bir seçenek yok
    Web tabanlı API’lerde okunabilir payload’ları daha çok tercih ederim; ama genelde JSON kullanılırken tip kesinliği gevşiyor ve backend dilleri arasında birlikte çalışabilirlik sorunları çıkıyor. Özellikle Node.js’te JSON.parse bir şema eşleme uygulaması gibi kullanılıyor
    Bunu düzgün yapmak için şemadan encoder ve decoder’ları açıkça üretmek gerekir; bu da JS bağlamında JSON kullanmanın avantajını bir ölçüde azaltır

    • Performans konusunda endişelenip gRPC’yi değerlendirecek kadar hassassanız, aynı anda Node.js’i stack’in yakınına koymak neden sorun olmuyor, merak ediyorum
    • Katılıyorum; JS şema sorunu için Zod çok yardımcı oluyor
      Microsoft’un TypeSpec projesini de izliyorum: typespec.io
    • proto’nun başlıca avantajı, birden fazla dil arasındaki birlikte çalışabilirliktir
      Tek dilli bir teknoloji stack’iniz varsa önemi azalır. Ayrıca Google’ın ana dilleri dışında bir şey kullanıyorsanız deneyimin o kadar iyi olmama ihtimali yüksek
    • 2023’te veri merkezi RPC’si için TCP tabanlı olmayan bir protokol olan Homa hakkında bir sunum vardı: https://youtu.be/xQQT8YUvWg8?si=g3u5TogBe0_QpPpj
  • gRPC, Google dışındaki geri kalan insanlar için gereksiz yere erişilmesi zor hissettiriyordu
    gRPC JS istemcisi gereksiz yere ağır ve oldukça opak. Fikir iyi, ama REST’in “basitliğine” alışkın olanlara kıyasla uygulaması hayal kırıklığı yaratıyor

    • Frontend/backend sınırında REST/JSON cephesi ile RPC/protobuf/gRPC cephesi çatışıyor
      RPC, veri modelinin kardinalitesini veya ilişkilerini tek bir kuralcı kalıba zorla uydurmak zorunda olmadığı için anlamsal olarak bakımı daha kolay. API’lerin hızla değiştiği bir dünyada güzel RESTful varlıkları tutturmak zor; büyük ekiplerde ve değişen gereksinimler/sahipliklerde servis odaklı tasarım daha iyi
      Frontend tarafı backend sistemlerini bakımını yapmaz. Anlaşılması kolay API’ler ister ve REST ile soyutlanabilen varlıklar ister. Bu tür tasarımın nihai faydalanıcısıdır
      REST’e harcanan emek, API satan ve üçüncü taraf geliştiricilerin ana müşteri olduğu şirketlerde anlamlıdır
      Backend geliştirmede protobuf ve ikili wire encoding daha kolaydır. API’yi tanımlayıp statik tipli bir şekilde servisler arasında paylaşabilirsiniz; mesaj kodlama/kod çözme süresi de azalır. JSON ne anlamsaldır ne de tiplenmiştir, ayrıca overhead’i de yüksektir
      Buna karşılık frontend metin ve JSON’u native olarak işler. Protobuf tanımlarını indirmek ya da ikili veriyi ikinci sınıf vatandaş gibi ele almak istemez; araçlarla da temiz şekilde uyuşmaz
      gRPC’de yönlendirme, yeniden deneme, yan kanallar, streaming ve protokol sonlandırma semantiği iyi yerleşmiştir, ancak bunlar frontend’e neredeyse hiç görünmez. Hepsi backend tüketicileri içindir
      Sonuçta bu %100 frontend/backend araç uçurumu ve arayüz ile kullanılabilirlik uyumsuzluğudur
    • REST, HTML’e benzer
      Temelde kaynağını görebilirsiniz, insanlar tarafından okunabilir ve incelemesi kolaydır
      gRPC, makinelerin birbirleriyle verimli konuşması içindir; ister kodlama ister istek/yanıt inceleme olsun, insan araya girince biraz rahatsız edicidir
      Bağlam ve hedefler farklı olduğu için bu kullanılabilirlik farkı anlaşılır
    • Resmi gRPC JavaScript implementasyonu biraz vasat
      Bana göre buf.build tarafındaki implementasyon iyi
      https://buf.build/blog/protobuf-es-the-protocol-buffers-type...
    • gRPC iyi bir fikir, ama benim sahip olmadığım Google tarzı problemler için çözümlerle ağırlaşmış
      Sözleşmeli ikili RPC gibi bir protokole ihtiyaç var gibi göründüğü için pek çok şeyi seçmişler sanki; ancak GoLang’den uzaklaştıkça giderek kötüleşiyor
    • gRPC’nin parladığı kullanım alanları var. Streaming bunlardan biri; tek bir “bağlantı” içinde mesaj akışlarını şeffaf biçimde gönderebiliyor
      Basit CRUD servisleri için REST de yeterlidir