1K Views
September 20, 25
スライド概要
REST 開発者のための Go による gRPC 開発入門 1
はじめに 今日はお越しいただきまことにありがとうございます。 この講座は REST での API 開発を行ってきたが、 gRPC による API 開発は経験がない。 マイクロサービスアーキテクチャでよく耳にする gRPC だが実際にどのようなものか? 開発の始め方はどういうものか? を知りたいなという人に向けて資料を作りました。 2
自己紹介 小山由人(こやまよしひと)と申します。 株式会社 UPSIDER 所属のソフトウェアエンジニアです。 2017 年にキャリアをスタートし、 Java や Go を使って Web API の開発をしてきまし た。 2024 年から UPSIDER にうつり、 gRPC を使った API の開発に携わっています。 3
アジェンダ gRPC ってなんだ? REST との比較 proto ファイルを書いてみよう Go で gRPC サーバーを実装してみよう Go で gRPC クライアントを実装してみよう まとめ 4
gRPC ってなんだ? REST との比較 5
gRPC とは gRPC とは Google が開発した RPC (Remote Procedure Call) フレームワークです。 RPC は直訳すると遠隔の手続き(関数)を呼び出す行為 REST のようにURLやHTTPメソッドでリソースを操作するのではなく、関数名と引数 で API を呼び出す 6
gRPC とは g の意味は実はバージョンごとに異なる(good とか green とか) https://grpc.github.io/grpc/core/md_doc_g_stands_for.html 7
gRPC とは gRPC は複数のプログラミング言語(Go、Java、PHP、Python)と複数のプラットフ ォーム(Linux、macOS、Windows、iOS、Android)に対応しています。 そして gRPC ではProtocol Buffers というものを用いてデータ定義をします。 こんな感じに定義された関数を呼び出します。 rpc 関数名 (引数) returns (戻り値); たとえば、 rpc Hello (HelloRequest) returns (HelloResponse); なら Hello が関数名、 HelloRequest が引数、 HelloResponse が戻り値です。 8
gRPC とは こういった型を .proto 拡張子がつく proto ファイルに定義します。 .proto ファイルは任意の言語のクライアント/サーバー用コードにコンパイルすることが できます。 9
gRPC とは gRPC による API の開発はこの Protocol Buffers を用いて proto ファイルを作ることか ら始まります。 Protocol Buffers には型があり、Protocol Buffers から生成されたコードにも同様の型付 けが行われます。 このように自ずとスキーマファーストの開発になるのが gRPC が選択される1つの理 由です。 10
gRPC とは gRPC のもう一つの特徴として HTTP/2 を利用した高速通信があります。 REST で開発する際は HTTP/1.1 を利用することが多いです。 gRPC は HTTP/2 を利用することのメリットとして、通信が高速であるということがあ ります。 11
gRPC とは HTTP/1.1 の場合、通常は 1リクエスト=1レスポンス=1つのTCPコネクション という扱 いでした。 複数のリクエストを同時に処理したい場合は、TCPコネクションを複数張る必要があ りました。 12
gRPC とは HTTP/2 は 1 つの TCP コネクションの中で複数のストリームを多重化できます。 図の下部では「ストリームID 1」「ストリームID 2」として、同じTCPコネクションの上 で並行して通信している様子が描かれています。 各ストリームは独立してやり取りできるため、同時に多数のリクエストを効率よく処 理可能です。 13
gRPC とは また、 HTTP/1.1 では通信するときに情報を主にテキストでやりとりします。 一方、HTTP/2では送受信するデータはバイナリにシリアライズされて送られます。 データ量が圧縮されるためリソースが効率的に使用されます。 さらに HTTP/2 では「ヘッダ圧縮」という仕組みがあります。 HTTP/2 では HPACK という方式でヘッダを圧縮するようにします。 その結果、繰り返しのヘッダ送信によるデータ量が減り、効率が良くなります。 14
gRPC とは それから gRPC の特徴としてストリーミングにも対応しています。 ストリーミングは「1回のコネクションを張りっぱなしにして、複数のメッセージを継 続的にやり取りする方式」です。 なお、REST でもサーバーからの一方向配信に SSE、双方向には WebSocket を使う選 択肢があります。 gRPC はフレームワークでストリーミングを標準化している点が利点です。 15
gRPC とは gRPC で対応できる通信方式は以下の4つです。 Unary (単発) RPC Server streaming RPC Client streaming RPC Bidirectional (双方向) streaming RPC 16
Unary RPC クライアントとサーバーのリクエストとレスポンスが1対1 17
Server streaming RPC クライアントのリクエストに対してサーバーが複数のレスポンスを返す たとえばイベント情報やニュースフィードなどの継続的なリアルタイム更新などに 使えます 18
Client streaming RPC クライアントからサーバーに対して複数のリクエストを送る たとえば大きなファイルの分割アップロードに使えます 19
Bidirectional streaming RPC クライアントのリクエストから開始して双方向にやりとりできる たとえばチャットアプリに使える 20
gRPC の課題 HTTP/2 に対応していない技術があり HTTP/2 非対応問題にあたる可能性がある ブラウザとの通信には gRPC-Web というプロキシーを利用する必要がある 言語により .proto ファイルによって生成されるコードが言語によって一部機能非 対応であったりする 外部公開には REST のほうが向いている ほぼすべての言語・フレームワークに REST/HTTP クライアントがある gRPC だと「protobufを理解してツールを入れて…」と学習コストが障壁にな る REST でも十分はやい 秒間数千件程度であれば REST でも十分高速 パフォーマンス観点ではデータベースやキャッシュも重要 21
Work これからクイズを出します。 出題内容は今日これまでに学んできた内容をもとにしています。 22
Work クイズの答えを考える際のポイントがあります。 クイズの答えを検索したり生成 AI に聞かずに自身の記憶を頼りにしてください。 答えがわからなくても大丈夫です。 正しい答えを思い出すことが目的ではなく、思い出す行為そのものが目的です。 思い出そうとすることで記憶への定着がはかれます。 23
Work ではクイズです。 24
Work 以下のクイズに対する回答を考えてみてください! gRPC 、 HTTP/2 を使うことで得られるメリットとは何でしょうか? gRPC が対応する 4 種類の通信方式をあげてください gRPC の課題としてどのようなものがあげられるでしょうか? 25
proto ファイルを書いてみよう 26
proto ファイルを書いてみよう gRPC では Protocol Buffers を使用してサービスのインターフェースを定義します。 .proto を拡張子とするファイルにサービスのメソッド、リクエストとレスポンスの型を 定義します。 .proto ファイルは gRPC サービスのインターフェースを定義するためのものです。 27
proto ファイルを書いてみよう 例えばこんな感じ。 syntax = "proto3"; option go_package = "gen/grpc"; package greeting; service GreetingService { rpc SayHello (HelloRequest) returns (HelloResponse); } message HelloRequest { string name = 1; } message HelloResponse { string message = 1; } 28
proto ファイルを書いてみよう では、1つずつ解説していきます。 29
syntax は Protocol Buffers のバージョン 現在は proto2 と proto3 があるが、今回は最新の proto3 を使う syntax = "proto3"; option go_package option go_package = "gen/grpc"; package package greeting; 間 は Go で生成されるコードのパッケージ名 は .proto ファイル内で定義されるメッセージやサービスの名前空 30
service service GreetingService { rpc SayHello (HelloRequest) returns (HelloResponse); } rpc SayHello (HelloRequest) returns (HelloResponse); RPC メソッドを定義 引数は HelloRequest 型 戻り値は HelloResponse 型 1 つの service に複数の RPC メソッドを定義できる は SayHello という 31
message message HelloRequest { string name = 1; } message HelloResponse { string message = 1; } message とは構造化されたデータ型のこと message HelloRequest とは HelloRequest という型を定義 string name = 1; は name というフィールド string は文字列型を意味する。 1 というようにフィールド番号を指定する 32
message message HelloRequest { string name = 1; } message HelloResponse { string message = 1; } は HelloResponse という型 string message = 1; は message というフィールド message HelloResponse { ... } 33
proto ファイルを書いてみよう 以上のように proto ファイルにサービスのメソッド、リクエストとレスポンスの型を定 義することから gRPC 開発は始まります。 proto ファイル内に定義できることをもう少し解説していきます。 34
スカラー型とメッセージ型 Protocol Buffers では値に型を定義します。 型には大きく分けてスカラー型とメッセージ型があります。 35
スカラー型とは スカラー型とは「基本的なデータ型」のこと。 Protocol Buffers で利用できるスカラー型は例えば以下のようなものがあります。 型 説明 double 64ビットの浮動小数点数 float 32ビットの浮動小数点数 int32 32ビットの符号付き整数 bool 真偽値 string UTF-8 文字列または 7 bit ASCII 文字列 bytes 任意のバイト配列 36
メッセージ型とは メッセージ型とは、フィールドを持つ構造化されたデータ型のこと。 syntax = "proto3"; message Card { string card_id = 1; string user_id = 2; string last_four_digits = 3; } メッセージ型は1つのprotoファイル内で複数定義できる。 各フィールドにはスカラー型や他のメッセージ型を指定できる。 フィールドごとにユニークな番号を指定する必要がある。 この番号はフィールドを識別するために使われる。 37
メッセージ型とは 運用中にフィールドを削除する場合、思わぬトラブルを避けるために番号を再利用せ ずに新しい番号を割り当てる必要があります。 不要になるフィールドは deprecated オプションをつけて非推奨とするか、 reserved で 他の開発者が誤って使わないことができます。 syntax = "proto3"; message Card { string card_id = 1; string user_id = 2; string last_four_digits = 6; string brand = 7 [deprecated = true]; // reserved は番号かフィールド名指定、 to や max といったキーワードも使える reserved 3 to 5; // フィールド番号 3 から 5 は予約済みなので使用できない } 38
repeated フィールド 配列を定義するときには repeated キーワードを使います。 syntax = "proto3"; message Card { string card_id = 1; string user_id = 2; string last_four_digits = 3; repeated string tags = 4; // tags フィールドは文字列の配列 } 39
enum 列挙型を定義するときには enum キーワードを使います。 syntax = "proto3"; enum Status { UNKNOWN = 0; // デフォルト値。先頭は必ず 0 にする ACTIVE = 1; INACTIVE = 2; BANNED = 3; } message Card { string card_id = 1; string user_id = 2; string last_four_digits = 3; Status status = 4; // status フィールドは Status 列挙型 } 40
map
マップ型を定義するときには map<key_type, value_type> を使います。
syntax = "proto3";
message Money {
string currency = 1; // "JPY", "USD" など
int64 amount = 2;
// 最小貨幣単位(JPYなら円, USDならセント)
}
message SpendPolicy {
string card_id = 1;
// カテゴリ -> 上限額(例: "TRAVEL" -> ¥50,000, "MEALS" -> ¥3,000)
map<string, Money> limit_by_category = 2;
}
41
oneof キーワードを使うと複数のフィールドのうち1つだけが設定されることを保証 できます。 oneof syntax = "proto3"; message Contact { oneof contact_info { string email = 1; string phone = 2; } } 42
Well Known Types Protocol Buffers にはよく使われるデータ型をあらかじめ定義した「Well Known Types」 があります。 これらは Google が提供する標準的なメッセージ型で、よく使われるデータ構造を簡単 に扱うことができます。 google.protobuf.Timestamp : タイムスタンプを表す google.protobuf.Duration : 時間の長さを表す 43
Work 44
Work では、ここまでの内容をもとにクイズを出します。 回答を考えてみましょう。 先に出したクイズも混ぜてあります。 スカラー型、メッセージ型とはどういうものでしたか? repeated フィールドとはどのようなものでしたか? Well Known Types にはどのようなものがありましたか? gRPC 、 HTTP/2 を使うことで得られるメリットとは何でしょうか? gRPC が対応する 4 種類の通信方式をあげてください 45
gRPC サーバーを Go で実装 46
前提条件 Go 1.25 を使用します。 macOS を前提にしています。 47
準備 必要なツールをインストールしましょう。 proto ファイルからコードを生成するために protoc を使います。 # Protocol Buffers コンパイラ brew install protobuf # インストール 確認 which protoc 次に、 Go 用の gRPC プラグインをインストールします。 # Go 用の gRPC プラグインインストール go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest # インストール確認 which protoc-gen-go which protoc-gen-go-grpc 48
proto ファイルを作ってみよう 任意のディレクトリを作成 mkdir grpc-hands-on cd grpc-hands-on proto ファイルを保存するディレクトリを作成 mkdir proto proto 下に hello.proto ファイルを作成 touch proto/hello.proto 49
hello.proto に以下を記述 syntax = "proto3"; option go_package = "gen/grpc"; package myapp; service GreetingService { rpc Hello (HelloRequest) returns (HelloResponse); } message HelloRequest { string name = 1; } message HelloResponse { string message = 1; } 50
自動生成されるファイルの保存先ディレクトリを作成 mkdir -p gen/grpc 51
では protoc コマンドで Go コードを自動生成します。 cd proto protoc --go_out=../gen/grpc --go_opt=paths=source_relative \ --go-grpc_out=../gen/grpc --go-grpc_opt=paths=source_relative \ hello.proto --go_out=../gen/grpc 力 : メッセージ型の Go コードを gen/grpc ディレクトリに出 --go_opt=paths=source_relative して相対パスにする --go-grpc_out=../gen/grpc リに出力 : 出力先のパスを実行した proto ファイルに対 : gRPC サービスの Go コードを gen/grpc ディレクト --go-grpc_opt=paths=source_relative に対して相対パスにする : 出力先のパスを実行した proto ファイル 52
これで gen/grpc ディレクトリに以下の2つのファイルが生成されます。 hello.pb.go : メッセージ型の Go コード hello_grpc.pb.go : gRPC サービスの Go コード 生成されるファイルを確認してみましょう。 53
たとえば HelloRequest は proto ファイルでは name フィールドをもつメッセージ型とし
て定義されていました。
syntax = "proto3";
message HelloRequest {
string name = 1;
}
生成された hello.pb.go ファイルでは以下のような Go の構造体として表現されます。
type HelloRequest struct {
state
protoimpl.MessageState `protogen:"open.v1"`
Name
string
`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache
protoimpl.SizeCache
}
54
また、構造体にはいくつかのレシーバが定義されています。 たとえば、 Name フィールドの値を取得するための GetName メソッドが定義されてい ます。 func (x *HelloRequest) GetName() string { if x != nil { return x.Name } return "" } 55
では service に定義された RPC メソッドはコンパイル後はどのように表現されるでしょ うか? service GreetingService { rpc Hello (HelloRequest) returns (HelloResponse); } GreetingService は hello_grpc.pb.go ファイルで以下のように定義されています。 サーバーサイドで利用する箇所を見ていきます。 56
GreetingServiceServer というインターフェースが自動で生成されています。 type GreetingServiceServer interface { Hello(context.Context, *HelloRequest) (*HelloResponse, error) mustEmbedUnimplementedGreetingServiceServer() } 57
GreetingServiceServer インターフェースには Hello メソッドと mustEmbedUnimplementedGreetingServiceServer メソッドが含まれています。 type GreetingServiceServer interface { Hello(context.Context, *HelloRequest) (*HelloResponse, error) mustEmbedUnimplementedGreetingServiceServer() } このインターフェースを実装するような構造体を自分で作成することで gRPC サーバー がつくれます。 mustEmbedUnimplementedGreetingServiceServer は UnimplementedGreetingServiceServer を埋め込みなさいという意味です。 UnimplementedGreetingServiceServer も protoc で自動生成され GreetingServiceServer と同ファイルに定義されています。 58
ここで UnimplementedGreetingServiceServer を見てみます。 type UnimplementedGreetingServiceServer struct{} func (UnimplementedGreetingServiceServer) Hello(context.Context, *HelloRequest) (*HelloResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Hello not implemented") } func (UnimplementedGreetingServiceServer) mustEmbedUnimplementedGreetingServiceServer() {} Hello が呼び出されたときに Unimplemented エラーを返す実装と mustEmbedUnimplementedGreetingServiceServer の空実装があります。 もし、新たに Hello2 という関数が定義されて protoc でコンパイルすると自動で UnimplementedGreetingServiceServer にも Hello2 が追加されます。 59
この UnimplementedGreetingServiceServer は自分でサーバー実装するときの構造体に 埋め込むことで効果が発揮されます。 type myServer struct { pb.UnimplementedGreetingServiceServer } 埋め込みを利用することで自身で定義した myServer 構造体に Hello と mustEmbedUnimplementedGreetingServiceServer メソッドが移譲されることになりま す。 UnimplementedGreetingServiceServer を埋め込まない場合、たとえば Hello2 という新 しい RPC メソッドが追加されたときに GreetingServiceServer インターフェースには Hello2 が追加されるが、自身の実装には Hello しかないため GreetingServiceServer イ ンターフェースを実装しないことになりビルドエラーになります。 60
type myServer struct { pb.UnimplementedGreetingServiceServer } このように Go の埋め込みを利用することで、将来 GreetingService に新しい gRPC の メソッドが追加された場合でもビルドが壊れないようになります。 61
サーバー側の実装 では、サーバー側の実装をしていきましょう。 go のプロジェクトを初期化し、必要なライブラリをインストールします。 go mod init github.com/yourusername/grpc-hands-on go get -u google.golang.org/grpc go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc サーバーの実装は cmd/server に main.go ファイルを作成して以下のように記述しま す。 mkdir -p cmd/server touch cmd/server/main.go 62
まず、 GreetingServiceServer インターフェースを実装するサーバーを作成してみます。 myServer という構造体を作ります。 このとき UnimplementedGreetingServiceServer を埋め込みます。 // 前方互換性をたもつために UnimplementedGreetingServiceServer を埋め込む type myServer struct { pb.UnimplementedGreetingServiceServer } // サーバーのコンストラクタ func NewMyServer() *myServer { return &myServer{} } 63
次に myServer の Hello メソッドの振る舞いを定義します。
今回は HelloRequest の Name フィールドを受け取り、HelloResponse の Message フィ
ールドに "Hello, {Name}!" というメッセージを返すようにします。
func (s *myServer) Hello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) {
log.Printf("received: %v", req.GetName())
return &pb.HelloResponse{
Message: fmt.Sprintf("Hello, %s!", req.GetName()),
}, nil
}
64
次に、 gRPC サーバーを起動するコードを書いてみます。
package main
import (
// 略
pb "grpc-hands-on/gen/grpc"
)
func main() {
port := 50051
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
// ポイントはここ
server := grpc.NewServer()
pb.RegisterGreetingServiceServer(server, NewMyServer())
// ここは動作確認時に重要になる
reflection.Register(server)
log.Printf("gRPC server is starting on port %d...", port)
if err := server.Serve(listener); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
type myServer struct {
pb.UnimplementedGreetingServiceServer
}
func NewMyServer() *myServer {
return &myServer{}
}
func (s *myServer) Hello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloResponse, error) {
log.Printf("received: %v", req.GetName())
return &pb.HelloResponse{
Message: fmt.Sprintf("Hello, %s!", req.GetName()),
}, nil
}
65
ここで重要なのはこちらです。 server := grpc.NewServer() pb.RegisterGreetingServiceServer(server, NewMyServer()) grpc.NewServer() で生成される server は gRPC のサーバインスタンスです。 まだリッスンもしていません。 66
server := grpc.NewServer() pb.RegisterGreetingServiceServer(server, NewMyServer()) RegisterGreetingServiceServer は自動生成した hello_grpc.pb.go ファイルに定義されて います。 第一引数に gRPC の server 変数を、第二引数には今回作成した GreetingServiceServer インターフェースを実装するサーバーを渡すことで server に GreetingService が登録さ れます。 この作業をサーバー起動前に実施することでこの gRPC サーバーは Hello という RPC メ ソッドを提供できるようになります。 67
では、このサーバーを起動してみましょう。 % go run cmd/server/main.go 2025/08/28 16:33:18 gRPC server is starting on port 50051... 68
動作確認 動作確認ですが gRPC クライアントとして grpcurl を使って確認します。 brew install grpcurl grpcurlは、gRPCサーバーに対してコードを書かずにリクエストを送れる cURL 風のCLI です。 69
なお、grpcurl は gRPC サーバーが提供するサービスの情報を取得するためのリフレク ションという機能をサーバー側で ON にしておく必要があります。 先ほど実装したサーバー側の実装でも reflection.Register(server) と記述をすることで grpcurl でアクセスができます。 実は proto ファイルが有ればサーバー側にリフレクション機能がなくてもアクセスでき ますが、今回はサーバー側にリフレクション機能を実装しています。 70
では、実際に Hello メソッドを呼び出してみましょう。
$ grpcurl -plaintext -d '{"name": "Golden Retriever Pan Cakes"}' localhost:50051 myapp.GreetingService/Hello
{
"message": "Hello, Golden Retriever Pan Cakes!"
}
リクエストに json で指定した name フィールドの値がレスポンスの message フィール
ドに反映されていることがわかります。
なお、grpcurl 以外にも Postman などの GUI ツールでも gRPC サーバーにアクセスでき
ますので好きなツールを使ってみてください。
71
gRPC クライアントを Go で実装 72
gRPC クライアントを Go で実装 gRPC サーバーを呼び出すためのクライアントコードを実装してみましょう。 次のような仕様とします。 このクライアントを実行すると、「gRPC クライアントを開始した」旨のメッセージが標準出力される。 画面の案内に従って、任意の名前を入力して Enter を押す。 クライアントはその名前をサーバへ送り、サーバからの応答メッセージを受け取って表示します。 入力→送信→表示を何度でも繰り返せます。終了したいときはターミナルで Ctrl+C を押します。 クライアント側の実装は cmd/client に main.go ファイルを作成して以下のように記述し ます。 mkdir -p cmd/client touch cmd/client/main.go 73
main.go には以下のように記述をします。
package main
import (
// 略
pb "grpc-hands-on/gen/grpc"
)
func main() {
fmt.Println("gRPC クライアントを起動するよ...")
target := "localhost:50051"
conn, err := grpc.NewClient(
target,
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
log.Fatal("Connection failed.")
return
}
defer conn.Close()
client := pb.NewGreetingServiceClient(conn)
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("好きな名前を入力してエンターキーを押してね: ")
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
req := &pb.HelloRequest{
Name: name,
}
res, err := client.Hello(context.Background(), req)
if err != nil {
fmt.Printf("gRPC サーバーから返答がこないよ: %v\n", err)
break
}
fmt.Printf("やった! gRPC サーバーから返答がきたよ: %s\n\n", res.GetMessage())
}
}
74
ポイントになるのはこちら。 target := "localhost:50051" conn, err := grpc.NewClient( target, grpc.WithTransportCredentials(insecure.NewCredentials()), ) NewClient で gRPC サーバーへのコネクションを作成しています。 target に接続先のアドレスをしていします。 grpc.WithTransportCredentials(insecure.NewCredentials()) は TLS を使わない設定です。 75
作成した connection を使ってクライアントを作成します。 client := pb.NewGreetingServiceClient(conn) NewGreetingServiceClient は protoc で生成された hello_grpc.pb.go ファイルに定義され ています。 これを利用することで GreetingService のサーバーにアクセスするクライアントが作成 できます。 76
こちらでリクエストで送る内容を生成して client.Hello でサーバーの Hello 関数が呼び出 されます。 req := &pb.HelloRequest{ Name: name, } res, err := client.Hello(context.Background(), req) 77
クライアントを実行 では実際に動かしてみましょう。 まずはサーバーを起動して go run cmd/server/main.go 次に別ターミナルでクライアントを起動します。 go run cmd/client/main.go クライアントの画面指示に従って入力するとサーバーからのレスポンスが返ってくるは ずです。 サーバー側にもクライアントからリクエストを受け取ったログが出力されているはず です。 78
Work 79
Work これが最後のクイズです! 次のコマンドがどういうことをするコマンドかを説明してください protoc --go_out=../gen/grpc --go_opt=paths=source_relative \ --go-grpc_out=../gen/grpc --go-grpc_opt=paths=source_relative \ hello.proto gRPC 、 HTTP/2 を使うことで得られるメリットとは何でしょうか? 80
まとめ 81
まとめ これで終了です。 gRPC の概要、 REST の比較から始めました。 REST はシンプルで学習コストが低い一方、 gRPC はスキーマファーストで型安全、高 速、双方向ストリーミングが可能などの特徴があります。 また、 proto ファイルの書き方、 gRPC サーバーとクライアントの Go での実装方法、 エラーハンドリングについても説明しました。 今日のハンズオンをぜひお手元で試してみてください。 82
まとめ 今回の内容をもとにより発展的な内容を学ぶとしたらたとえば次のキーワードが上が ると思います。 エラーハンドリング:エラーコード、バリデーション、リトライ メタデータの利用 ロードバランシング インターセプター(認証認可、ロギング、トレーシング) ストリーミングの実装 Kubernetes 環境に gRPC のサービスをデプロイ grpc-gateway や connect を用いた JSON/HTTP1.1 クライアント互換性の確保 次回以降の機会があればこれらについて深堀りする講義をしてみたいと思います。 83 その際は是非お越しください。
参考資料 作ってわかる! はじめてのgRPC https://zenn.dev/hsaki/books/golang-grpc-starting スターティングgRPC https://nextpublishing.jp/book/11746.html WEB+DB PRESS Vol.110 特集2 速習 gRPC https://gihyo.jp/magazine/wdpress/archive/2019/vol110 84
参考資料 Software Design 2023 年 7 月号 gRPC で始める Web API 開発 https://gihyo.jp/magazine/SD/archive/2023/202307 gRPC Up & Running https://www.oreilly.com/library/view/grpc-up-and/9781492058328/ 85
参考資料 gRPC 公式ドキュメント(Go) https://grpc.io/docs/languages/go/ grpc/grpc-go リポジトリ https://github.com/grpc/grpc-go Protocol Buffers 公式ドキュメント https://protobuf.dev/overview/ HTTP/2 RFC https://datatracker.ietf.org/doc/html/rfc7540 日本ネットワークインフォメーションセンター ニュースレターNo.68 https://www.nic.ad.jp/ja/newsletter/No68/0800.html 86