0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go + gRPC + Protocol Buffers 入門 〜 go_package の正しい設定とディレクトリ構成でハマらないために 〜

Posted at

はじめに

Go で gRPC を使い始める際に、.proto ファイルから自動生成されたコードが思わぬディレクトリ構造に配置されてしまい、インポートがうまくいかない……という経験はありませんか?
本記事では、Go Modules を使ったプロジェクトで、gRPC + Protocol Buffers の開発環境を正しく構築し、スムーズにコード生成・インポートを行うまでの流れを整理します。


前提

  • OS: Mac など(Homebrew を利用できる環境)
  • Go バージョン: go1.23.6 以上
  • Go Modules: 有効化済み

1. プロジェクトの作成と Go Modules の初期化

まずは、新しいディレクトリを作り、そこをプロジェクトのルートとします。ここでは、仮に my-grpc-project という名前とします。

mkdir my-grpc-project
cd my-grpc-project
go mod init github.com/yourusername/my-grpc-project
  • go.mod が作成され、モジュールパスが github.com/yourusername/my-grpc-project に設定されます。

2. Protocol Buffers Compiler (protoc) とプラグインのインストール

2-1. protoc のインストール

brew install protobuf
protoc --version
# libprotoc 23.x など、バージョンが表示されればOK

2-2. 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
  • これらは通常 $(go env GOPATH)/bin にインストールされます。
  • $PATH$(go env GOPATH)/bin を含めるよう設定しておきます。

3. ディレクトリ構成を決める

最初に、proto ディレクトリを作成し、その下にサービスごとにフォルダを作るやり方がわかりやすいです。

my-grpc-project/
├── go.mod
└── proto/
    └── greeter/
        └── greeter.proto

ここでは、greeter サービスを想定し、proto/greeter フォルダに .proto ファイルを配置します。


4. .proto ファイルの作成

greeter.proto を以下のように作成します。

syntax = "proto3";

package greeter;

// go_package のインポートパスは、go.mod のモジュールパス + ディレクトリ
option go_package = "github.com/yourusername/my-grpc-project/proto/greeter;greeter";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}
  • package greeter;
    Protocol Buffers 上のパッケージ名
  • option go_package
    生成される Go コードのインポートパスとパッケージ名を指定
    例: "github.com/yourusername/my-grpc-project/proto/greeter;greeter"

5. コード生成

プロジェクトルート (my-grpc-project) で以下のコマンドを実行します。

protoc --go_out=paths=source_relative:. --go-grpc_out=paths=source_relative:. proto/greeter/greeter.proto
  • paths=source_relative オプションを使うと、.proto ファイルと同じディレクトリ (proto/greeter) に生成ファイルが配置されます。
  • 成功すると、以下のように .pb.go_grpc.pb.go が生成されます。
my-grpc-project/
├── go.mod
└── proto/
    └── greeter/
        ├── greeter.proto
        ├── greeter.pb.go
        └── greeter_grpc.pb.go

6. 依存関係を追加 (gRPC パッケージ)

生成されたコードを使ってサーバーやクライアントを実装するには、google.golang.org/grpc を依存関係に追加する必要があります。

go get google.golang.org/grpc@latest
go mod tidy

これで go.modgo.sum に必要な情報が書き込まれ、VSCode のインポートエラーなども解消されます。


7. 簡単な gRPC サーバー実装例

cmd/server/main.go など、エントリーポイントを用意して以下のように書きます。

package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "github.com/yourusername/my-grpc-project/proto/greeter"
)

type server struct {
    pb.UnimplementedGreeterServer
}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
    log.Printf("Received: %v", in.Name)
    return &pb.HelloResponse{Message: "Hello " + in.Name}, nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    log.Printf("server listening at %v", lis.Addr())
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

7-1. 実行

cd cmd/server
go run main.go
  • :50051 ポートで gRPC サーバーが起動します。
  • 別のターミナルで grpcurl などを使えばテストも可能です。

8. まとめ

  1. go.mod の初期化
    • go mod init github.com/yourusername/my-grpc-project
  2. Protobuf とプラグインのインストール
    • brew install protobuf
    • go install protoc-gen-go / protoc-gen-go-grpc
  3. .proto ファイルで go_package を設定
    • option go_package = "github.com/yourusername/my-grpc-project/proto/greeter;greeter";
  4. paths=source_relative オプションを付けて protoc 実行
    • 生成ファイルを .proto と同じフォルダへ配置
  5. 依存関係を go get で追加
    • go get google.golang.org/grpc@latest
  6. サーバー実装 & 起動

この流れで、モジュールパスとディレクトリ構造が一致し、VSCode のエラーも起こりにくくなります。
ぜひ試してみてください。何か詰まったらコメントなどで教えていただければ幸いです。


参考リンク

以上が、Go + gRPC + Protocol Buffers を使った開発フローの簡単なまとめです。皆さんの開発がスムーズに進むことを願っています!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?