gotoshin

主に学んだ事の自分メモ用です。記事に書くまでも無いような事はhttps://scrapbox.io/study-diary/に書いてます。

grpcコースをやってみる〜その2〜

www.youtube.com

環境構築

Protocol Buffer Compilerをinstall

Protocol Buffer Compiler Installation | gRPC

記載の通りbrew installしたらいけた

Goをビルドするためにプラグインをinstall

protoc-gen-go

prot ファイルで定義されたデータからgoのリクエスト・レスポンスデータを生成する

pkg.go.dev

protoc-gen-go-grpc

grpcフレームワークで動くgoのコードを生成する

pkg.go.dev

これで準備は完了

ユーザ新規作成の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は完成

詰まった箇所

問題

  1. 通常通りクラスを記載しても型を参照出来ないため、import文を追加する
  2. 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

成都度ファイルが増えることを防ぐため、生成前に削除するコマンドを追加する