Sejak gRPC diperkenalkan, gRPC menjadi sangat populer di kalangan komunitas pengembang API. Alasan mengapa gRPC menjadi begitu populer adalah dukungannya terhadap implementasi poliglot (server dan klien dapat ditulis dalam bahasa yang berbeda), fokusnya pada kinerja sejak awal (gRPC didasarkan pada HTTP/2) dan seperangkat alat yang hebat (penggunaan gRPC). protobuf» untuk deskripsi pesan dan layanan dan klien dapat dibuat secara otomatis tanpa menulis satu baris kode pun).

Hingga beberapa tahun yang lalu, keunggulan ini terbatas pada ponsel dan server dan tidak tersedia untuk pengembang front-end dan mereka masih harus menggunakan antarmuka REST. Hal ini disebabkan oleh keterbatasan HTTP/2 di browser. Misalnya

  1. Permintaan di browser tidak bisa dipaksakan menjadi HTTP/2.
  2. Bingkai HTTP/2 tidak tersedia secara langsung ke perpustakaan.

Datanglah grpc-web, upaya Google dan Improbable untuk mengimplementasikan spesifikasi gRPC untuk browser. Spesifikasi ini menggunakan HTTP/1.x dengan proxy gateway seperti Envoy (yang secara transparan menerjemahkan HTTP/1.x ke HTTP/2 yang diharapkan oleh server gRPC).

gRPC-web hanya mendukung streaming Unary dan sisi Server dalam mode grpcwebtext (kita akan membahas artinya di bagian selanjutnya)

Pada postingan kali ini kita akan mengimplementasikan server gRPC di golang dan mengimplementasikan klien dalam JavaScript menggunakan gRPC-web. Kita akan melihat contoh panggilan API streaming sisi server dan unary.

Jadi mari kita mulai.

Daftar Isi

  1. Prasyarat
  2. Definisi Protobuf
  3. Menerapkan API server Unary
  4. Mengkonsumsi API Unary
  5. Memperbaiki kesalahan komunikasi dengan Utusan
  6. Menerapkan streaming sisi Server
  7. Kesimpulan

Prasyarat

Kita perlu menginstal beberapa alat agar berhasil melewati posting ini.

  1. VS Codeatau editor kode pilihan Anda untuk menulis kode kami.
  2. Kompiler dan alat "Golang".
  3. Python3 — Kami akan menggunakan server HTTP python untuk melayani klien kami.
  4. Node (npm sudah dibundel dengan node) dan alat npx.
  5. Docker — Kami akan menjalankan proxy Envoy sebagai wadah buruh pelabuhan.
  6. protoc kompiler protobuf.
  7. Golang paket gRPC dan protobuf protoc plugin.
  8. protoc-gen-grpc-webplugin gRPC-web.

Ikuti petunjuk pemasangan untuk masing-masing alat. Saya melewatkan petunjuk di sini agar singkatnya, tetapi beri tahu saya jika Anda menghadapi kesalahan apa pun, saya akan dengan senang hati membantu.

Postingan ini sama sekali bukan postingan pengenalan untuk bahasa atau kerangka kerja apa pun yang digunakan di sini. Saya akan menghubungkan materi pengantar untuk masing-masing materi agar Anda dapat mengetahuinya dengan cepat.

Definisi Protobuf

Kami akan mulai dengan membuat definisi protobuf untuk layanan kami. Buat file calculator.proto dan letakkan di folder protos. Untuk saat ini, kami hanya akan menambahkan definisi layanan Unary dan mengembangkannya untuk menambahkan streaming sisi Server di bagian ke-2.

grpc-web
    ├── protos
    │   └── calculator.proto
    ├── server
    └── client

Kami telah menambahkan dua pesan yaitu AddRequest yang membutuhkan dua angka untuk dijumlahkan, AddResponse yang mengembalikan hasil penjumlahan dan layanan kalkulator dengan satu panggilan rpc Addyang mengambil AddRequest dan mengembalikan AddResponse.

Menerapkan API server Unary

Kami akan mengkompilasi file calculator.proto untuk kode go dengan bantuan protoc dan plugin go protobuf.

Buat folder calculatorpb di dalam folder server dan jalankan perintah berikut.

protoc calculator.proto --go_out=plugins=grpc:../server/calculatorpb/

Ini akan menghasilkan file calculator.pb.go dan struktur direktori Anda akan terlihat seperti ini.

grpc-web
    ├── protos
    │   └── calculator.proto
    ├── server
    │   └── calculatorpb
    │       └── calculator.pb.go
    └── client

Sekarang inisialisasi modul go dengan menjalankan perintah berikut di folder server.

go mod init github.com/kaysush/grpc-calculator

Ini akan menambahkan file go.mod ke folder server Anda. Membuat modul dari folder server kita akan memastikan kita dapat mengakses paket dalam file calculator.pb.go di file server.go yang akan kita tambahkan pada langkah berikutnya.

Mari kita implementasi servernya sekarang.

grpc-web
    ├── protos
    │   └── calculator.proto
    ├── server
    │   ├── calculatorpb
    │   │   └── calculator.pb.go
    │   ├── go.mod
    │   └── server.go
    └── client

Jalankan server.go

go run server.go

Anda akan melihat pesan Starting Calculator server di layar Anda.

Server gRPC kini siap melayani permintaan pada port 50551.

Mengkonsumsi API Unary

Sekarang server kita sudah berjalan, mari kita implementasi klien kita menggunakan gRPC-web.

Kompilasi file calculator.proto untuk JavaScript menggunakan plugin proto-gen-grpc-web.

protoc calculator.proto --js_out=import_style=commonjs,binary:../client --grpc-web_out=import_style=commonjs,mode=grpcwebtext:../client

Ini akan menghasilkan calculator_pb.js (yang memiliki definisi pesan) dan calculator_grpc_web_pb.js (yang memiliki implementasi klien kami).

grpc-web
    ├── protos
    │   └── calculator.proto
    ├── server
    │   ├── calculatorpb
    │   │   └── calculator.pb.go
    │   ├── go.mod
    │   └── server.go
    └── client
        ├── calculator_grpc_web_pb.js
        └── calculator_pb.js

Tambahkan file package.json ke folder client dengan konten berikut.

{
 "name": "grpc-calculator",
 "version": "0.1.0",
 "description": "gRPC-Web Calculator",
 "devDependencies": {
  "@grpc/proto-loader": "^0.3.0",
  "google-protobuf": "^3.6.1",
  "grpc": "^1.15.0",
  "grpc-web": "^1.0.0",
  "webpack": "^4.16.5",
  "webpack-cli": "^3.1.0"
 }
}

Tambahkan file client.js yang implementasi klien kami terhubung ke server gRPC kami.

Ingat bagaimana saya mengatakan kepada Anda bahwa Anda tidak perlu menulis kode apa pun untuk mengimplementasikan klien dengan gRPC.

Sekarang mari kita kemas kode JavaScript kita ke dalam file yang diperkecil.

npm install
npx webpack client.js

Ini harus mengunduh semua dependensi yang disebutkan dalam file package.json dan kemudian mengemas client.js ke dist/main.js dengan semua dependensi.

Buat file index.html yang mereferensikan file dist/main.js kita dan melakukan panggilan gRPC.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Calculator - gRPC-Web</title>
    <script src="dist/main.js"></script>
</head>
<body>
</body>
</html>

Struktur direktori Anda akan terlihat seperti ini sekarang.

grpc-web
    ├── protos
    │   └── calculator.proto
    ├── server
    │   ├── calculatorpb
    │   │   └── calculator.pb.go
    │   ├── go.mod
    │   └── server.go
    └── client
        ├── dist
        │   └── main.js
        ├── calculator_grpc_web_pb.js
        ├── calculator_pb.js
        ├── client.js
        ├── package.json
        └── index.html

Dari direktori klien, mulai server python untuk mulai menyajikan file kami.

python3 -m http.server 8081 &

Sekarang buka http://localhost:8081 dan buka konsol.

Anda akan melihat kesalahan di konsol. Anda akan mendapatkan satu atau semua kesalahan berikut.

  1. Permintaan Lintas Asal Diblokir
  2. ERR_CONNECTION_REFUSED

Ada dua masalah dengan implementasi server dan klien kami saat ini.

  1. Server kami tidak mengizinkan permintaan CORS dan
  2. Meskipun mendukung CORS, gRPC-web tidak mendukung HTTP/2 oleh karena itu kami memerlukan proxy gateway seperti Envoy untuk menerjemahkan permintaan HTTP/1.x yang berasal dari gRPC-web untuk server gRPC kami.

Memperbaiki kesalahan komunikasi dengan Utusan

Seperti yang dibahas di bagian sebelumnya, kita perlu menempatkan Envoy antara klien dan server kita untuk terjemahan transparan antara HTTP/1.x dan HTTP/2.

Kami akan menggunakan buruh pelabuhan untuk menjalankan proxy utusan kami. Kami akan menggunakan envoy.yaml standar dari gRPC-web hello world demo (tentu saja dengan port yang diubah sesuai implementasi kami)

Buat file buruh pelabuhan.

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

Buat gambar buruh pelabuhan.

docker build -t my-envoy:1.0 .

Sekarang jalankan wadah buruh pelabuhan utusan.

docker run -d -p 8080:8080 -p 9901:9901 --network=host my-envoy:1.0

Setelah utusan berjalan kita perlu mengubah port di client.js. Sekarang, alih-alih menyambung ke server gRPC langsung di 50551, kami akan menyambung ke utusan di 8080.

Kemas ulang client.js lagi.

npx webpack client.js

Muat ulang browser di http://localhost:8081 dan buka konsol.

Anda sekarang akan melihat keluaran Anda.

Menerapkan streaming sisi Server

Edit file calculator.proto dan tambahkan panggilan rpc streaming sisi server untuk menghasilkan angka Fibonacci.

protoc calculator.proto --go_out=plugins=grpc:../server/calculatorpb/Re-compile our proto files for both go and js.
protoc calculator.proto --js_out=import_style=commonjs,binary:../client --grpc-web_out=import_style=commonjs,mode=grpcwebtext:../client

Tambahkan implementasi server di server.go.

Tambahkan panggilan streaming di client.js kami.

Kemas ulang klien.

npx webpack client.js

Muat ulang browser dan Anda akan melihat angka fibonacci mengalir ke klien Anda.

Kesimpulan

gRPC-web adalah spesifikasi yang sangat matang untuk menghubungkan ke API gRPC langsung dari browser tanpa antarmuka REST di antaranya. Dengan semakin banyaknya layanan mikro yang menggunakan gRPC , gRPC-web sangat cocok dengan dunia API gratis REST.

Jika Anda menemukan kesalahan dalam kode saya atau memiliki pertanyaan umum, jangan ragu untuk memberikan komentar.

Sampai saat itu, Selamat Coding! :)