gRPC-Web ile uçtan uca gRPC

A. Kürşat Uzun
3 min readFeb 7, 2020

gRPC

gRPC Google tarafından kullanılıp geliştirilen, HTTP/2.0 üzerine inşa edilmiş çift yönlü iletişime imkan sunan açık kaynak RPC framework’üdür.

gRPC full-duplex stream özelliğini destekliyor bu sayede client bir istekde bulunurken aynı anda server’dan cevap alabilir. Half-duplex bir stream servisinde ise server client’ın isteğinin tamamlanmasını beklemek zorundadır. (Telefonu full-duplex, telsizi half-duplex olarak düşünebiliriz.)

Yazı gRPC-Web örneğini ele aldığından kısa tutmak adına gRPC’nin özelliklerini ve detaylarını şu yazıdan öğrenebilirsiniz.

gRPC-Web

gRPC-Web’in iki farklı implemantasyonu bulunuyor. Her ikiside henüz client-side ve server-side bi-directional stream özelliğini desteklemiyor.

gRPC-Web ile artık REST olmadan gRPC mimarisi uçtan uca kurulabilir. Bu işlemi gerçekleştirmek için gRPC-web’in kullandığı varsayılan proxy servisi Envoy’a ihtiyacımız var. Envoy client tarafından oluşturulan HTTP/1.1 isteklerini HTTP/2 isteklerine çevirir. (gRPC server’ı HTTP/2 isteklerini kabul eder)

gRPC-Web ve Envoy Proxy ile aracı olarak REST kullanmaya gerek kalmadı.

Adımlar

  1. Proto Dosyası
  2. Client Yapılandırılması
  3. Envoy Proxy
  4. Server Yapılandırması

Gerekli Yazılım ve Araçlar

Protocol Buffers/protobuf derleyicisi 

Server Side

- Go Lang
- gRPC’nin go implementasyonu
- gRPC Go eklentisi

Client Side

- npm
- gRPC-Web eklentisi
- docker (envoy için)

Server ve Client kodunu oluşturmamız için protobuf derleyicisine ihtiyacımız var. Öncelikle derleyiciyi bu adresten kurabilirsiniz. Gerekli kurulumları sizlere bırakıyorum.

1. Proto Dosyası

Protocol Buffers (diğer adıyla protobuf) Google tarafından geliştirilen dil ve platform bağımsız veri değişim formatıdır.

Country adında bir sınıf oluşturup, mevcut ülkeleri ve yeni bir ülkeyi ekleyebileceğimiz proto dosyası oluşturalım. REST’e benzer şekilde bu işlem için gerekli “GET” ve “POST” işlemi içeren proto dosyası:

syntax = “proto3”;package country;message Country {
int64 id = 1;
string name = 2;
string flag = 3;
}
message GetCountriesRequest {}message GetCountriesResponse {
repeated Country countries = 1;
}
message AddCountryRequest {
Country country = 1;
}
message AddCountryResponse {
string success = 1;
}
service CountryService {
rpc GetCountries(GetCountriesRequest) returns (GetCountriesResponse) {};
rpc AddCountry(AddCountryRequest) returns (AddCountryResponse) {};
}

2. Client Side

JavaScript Client side’ın stub dosyaları oluşturmak için gRPC-Web eklentisine ihtiyacımız var. Bu adresten gRPC-Web eklentisinin kurulum işlemini gerçekleştirin.

Proto dosyasından Client side stub’ı oluşturmak için şu komutu çalıştırın:

$ protoc --proto_path=./proto/ --js_out=import_style=commonjs:./client/ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./client/ ./proto/country.proto

Client için package.json şu şekilde

..."scripts": {
"dev": "parcel index.html"
},
...
“dependencies”: {
“grpc-web”: “¹.0.7”,
“google-protobuf”: “³.11.2”
},
“devDependencies”: {
“parcel-bundler”: “¹.12.4”
}

Örnek bir Get ve Post isteği ise şöyle:

index.js getCountries ve addCountry çağrıları.

npm install ile gerekli kütüphanelerin kurulumunu sağlayıp, npm run dev komutu ile uygulamayı ayaklandıralım.

$ npm install
$ npm run dev
Server running at http://localhost:1234

3. Envoy Yapılandırılması

Bu adresten docker’ın kurulumunu gerçekleştirin.

Envoy için gerekli DockerFile’ı oluşturalım:

FROM envoyproxy/envoy:latest
COPY ./envoy.yaml /etc/envoy/envoy.yaml
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml

Proxy ayarı için Envoy.yaml dosyası oluşturalım:

45. satırdaki port_value: 50051 değeri server side’ın portunu göstermeli

Bir docker image’ı oluşturalım:

docker build -t grpc-web-example/envoy -f ./Dockerfile .

Envoy container’ını çalıştıralım:

docker run -d -p 8080:8080 -p 9901:9901 --network=host grpc-web-example/envoy

Proxy’miz ayakta artık 8080 portuna gelen istekler Envoy tarafından dönüştürülüp 50051 portuna yönlendirilecek.

4. Server Side

Go’yu bu adresten kurabilirsiniz.
Go’ya gRPC’yi kurmak için komut satırından şu komutu çalıştıralım:

$ go get -u google.golang.org/grpc

Şimdi Go için protoc eklentisini indirelim:


$ go get -u github.com/golang/protobuf/protoc-gen-go

protoc-gen-go plugini $GOBIN adresine yüklenecek. protoc’un bu eklentiyi bulması için aşağıdaki komutu çalıştıralım:

$ export PATH=$PATH:$GOPATH/bin

Oluşturduğumuz proto dosyasından server stub’ını oluşturmak için aşağıdakı satırı çalıştıralım:

$ protoc — go_out=. *.proto

Oluşan protobuf dosyasını go’da module olarak yapılandırıp import edebiliriz. Oluşturduğumuz stub’ı kullanan go server örneği:

Go ve gRPC kullanan örnek server. Örneği kısa tutmak adına herhangi bir database bağlantısı yok.

Server hazır aşağıdaki komutla çalıştırabiliriz:

$ ~/grpc-web-example/server go run main.go

Sonuç

localhost:1234 adresini ziyaret edip tarayıcının konsoluna bakabilirsiniz:


{“countriesList”:[{“id”:1,”name”:”Turkey”,”flag”:”https://upload.wikimedia.org/wikipedia/commons/b/b4/Flag_of_Turkey.svg"},{"id":2,"name":"Israel","flag":"https://en.wikipedia.org/wiki/Flag_of_Israel#/media/File:Flag_of_Israel.svg"},{"id":2,"name":"Iran","flag":"https://tr.wikipedia.org/wiki/%C4%B0ran#/media/Dosya:Flag_of_Iran.svg"},{"id":2,"name":"China","flag":"https://tr.wikipedia.org/wiki/%C3%87in#/media/Dosya:Flag_of_the_People's_Republic_of_China.svg"}]}
index.js:48 {“success”:”Country added.”}

Uygulamanın kaynak kodlarına aşağıdan ulaşabilirsiniz.

https://github.com/akursat/grpc-web-example

--

--

A. Kürşat Uzun

Frontend developer and designer, science fiction enthusiast, practicing minimalism, and stoic in search of flow. Writing about design and code.