grpcコースをやってみる〜その2〜
環境構築
Protocol Buffer Compilerをinstall
Protocol Buffer Compiler Installation | gRPC
記載の通りbrew installしたらいけた
Goをビルドするためにプラグインをinstall
protoc-gen-go
prot ファイルで定義されたデータからgoのリクエスト・レスポンスデータを生成する
protoc-gen-go-grpc
grpcフレームワークで動くgoのコードを生成する
これで準備は完了
ユーザ新規作成のgrpc APIを作成
protoスキーマを定義する
ユーザのスキーマ
作成元のデータ
ユーザ新規作成時のレスポンスを元データとする
// /api/user.go type userResponse struct { Username string `json:"username"` FullName string `json:"full_name"` Email string `json:"email"` PasswordChangedAt time.Time `json:"password_changed_at"` CreatedAt time.Time `json:"created_at"` }
proto定義
// proto/user.proto option go_package = "github.com/simplebank/pb"; // シンタックス syntax = "proto3"; // パッケージ package pb; import "google/protobuf/timestamp.proto"; // どのパッケージに対してgoコードを生成するか // 下の記述によってpbフォルダ配下に生成される(フォルダは事前作成する必要あり) option go_package = "github.com/simplebank/pb"; message User { string username = 1; string full_name = 2; string email = 3; // デフォルトのprotoにはタイムスタンプ型は無いため、ライブラリを利用する google.protobuf.Timestamp password_changed_at =4; google.protobuf.Timestamp created_at=5; }
リクエスト・レスポンスのスキーマ
作成元のデータ
ユーザ作成のリクエスト
type createUserRequest struct { Username string `json:"username" binding:"required,alphanum"` Password string `json:"password" binding:"required,min=6"` FullName string `json:"full_name" binding:"required"` Email string `json:"email" binding:"required,email"` }
proto定義
syntax = "proto3"; package pb; import "user.proto"; option go_package = "github.com/simplebank/pb"; message CreateUserRequest { string username = 1; string full_name = 2; string email = 3; string password = 4; } // レスポンスは最初に作成したユーザ定義をそのまま返却する message CreateUserResponse { User user = 1; }
grpc APIを定義する
syntax = "proto3"; package pb; // 先ほど定義したスキーマを読み込み import "rpc_create_user.proto"; option go_package = "github.com/simplebank/pb"; service SimpleBank { rpc CreateUser (CreateUserRequest) returns (CreateUserResponse) {} }
これにてユーザ作成のAPIは完成
詰まった箇所
問題
- 通常通りクラスを記載しても型を参照出来ないため、import文を追加する
- import文が赤線でエラー表記となる
対策
解決するためには、拡張機能の説明に記載のある内容を参考にsetting.jsonに以下の内容を追記
"protoc": { "options": [ "--proto_path=protos", ] }
VSCodeを再起動して解消
同じ流れでログインユーザのgrpc APIを作成
通信タイプは?
シンプルなunaryで実施。
protoスキーマを定義する
リクエスト・レスポンスデータ
作成元のデータ
動画のものと比べて古い。
type loginUserRequest struct { Username string `json:"username" binding:"required,alphanum"` Password string `json:"password" binding:"required,min=6"` } type loginUserResponse struct { AccessToken string `json:"access_token"` User userResponse `json:"user"` }
- userResponseクラスは最初に定義したUserスキーマと同じため、流用可能
proto定義
syntax = "proto3"; package pb; import "user.proto"; option go_package = "github.com/simplebank/pb"; message LoginUserRequest { string username = 1; string password = 2; } message LoginUserResponse { string access_token= 1; User user = 2; }
grpc APIを定義する
service SimpleBank { rpc CreateUser (CreateUserRequest) returns (CreateUserResponse) {} // ログイン用に追加 rpc LoginUser (LoginUserRequest) returns (LoginUserResponse) {} }
go コードを生成する
grpc.io 公式からgoコード生成用のコマンドを引っ張ってきてMakefileに追記する
// Makefile proto: protoc --proto_path=proto --go_out=pb --go_opt=paths=source_relative \ --go-grpc_out=pb --go-grpc_opt=paths=source_relative \ proto/*.proto ・ ・ ・ .PHONY: postgres createdb dropdb migrateup migratedown migrateup1 migratedown1 sqlc server mock proto
ターミナル上でmake proto
を実行することでgoのコードが生成される
それぞれのファイルは今回作成したprotoファイルを元に生成されている
pb/sevice_simple_bank_grpc.pb.go
はサーバとクライアントのインターフェースとスタブを含んでいる
パッケージimoprtエラーを解消する
- 単純に
google.golang.org/grpc
パッケージが入っていない事が原因 go mod tidy
を実施することで不足分が入ってくる
Makefileを修正する
// Makefile proto: // 追加 rm -f pb/*go protoc --proto_path=proto --go_out=pb --go_opt=paths=source_relative \ --go-grpc_out=pb --go-grpc_opt=paths=source_relative \ proto/*.proto
生成都度ファイルが増えることを防ぐため、生成前に削除するコマンドを追加する