Tasuke HubLearn · Solve · Grow
#Go

GoによるgRPCマイクロサービス実践入門:Protocol Buffersから実装まで【2025年版】

マイクロサービス間の高速な通信を実現するgRPCについて、Go言語を使った実践的な開発手順を解説。Protocol Buffersでのサービス定義、コード生成、サーバーとクライアントの実装までを網羅します。

時計のアイコン19 September, 2025
TH

Tasuke Hub管理人

東証プライム市場上場企業エンジニア

情報系修士卒業後、大手IT企業にてフルスタックエンジニアとして活躍。 Webアプリケーション開発からクラウドインフラ構築まで幅広い技術に精通し、 複数のプロジェクトでリードエンジニアを担当。 技術ブログやオープンソースへの貢献を通じて、日本のIT技術コミュニティに積極的に関わっている。

🎓情報系修士🏢東証プライム上場企業💻フルスタックエンジニア📝技術ブログ執筆者

はじめに:gRPCとは? RESTと何が違うのか?

マイクロサービスアーキテクチャでは、サービス間の効率的な通信がシステムのパフォーマンスを大きく左右します。これまで主流だったREST (JSON over HTTP/1.1) は、その柔軟性と可読性の高さから広く使われてきましたが、パフォーマンスや型安全性に課題を抱えることもありました。

gRPCは、Googleによって開発された、これらの課題を解決するためのオープンソースのRPC (Remote Procedure Call) フレームワークです。

RESTと比較したgRPCの主な特徴:

  • 高いパフォーマンス: デフォルトでHTTP/2を通信プロトコルとして使用します。HTTP/2は、単一のTCP接続上で複数のリクエスト/レスポンスを並行して送受信できる「多重化」や、ヘッダー情報を圧縮する「ヘッダー圧縮」などの機能を持ち、通信効率が大幅に向上します。
  • Protocol Buffersによるシリアライズ: メッセージのシリアライズ(バイト列への変換)には、JSONやXMLの代わりに、バイナリベースのProtocol Buffers (Protobuf) を使用します。Protobufは非常にコンパクトで、エンコード・デコードが高速です。
  • 厳密なスキーマ定義: .protoというIDL (Interface Definition Language) ファイルでサービス(APIのメソッドやメッセージの構造)を厳密に定義します。これにより、サーバーとクライアント間での型の不一致を防ぎ、強力な型安全性を実現します。
  • 多様な通信パターン: 通常のリクエスト/レスポンス(Unary RPC)だけでなく、サーバーからクライアントへデータをストリーミングする、クライアントからサーバーへストリーミングする、あるいは双方向でストリーミングするといった高度な通信パターンをサポートします。

本記事では、Go言語を使って簡単なgRPCサービス(ユーザー情報を取得するサービス)を実装する手順をゼロから解説します。

ベストマッチ

最短で課題解決する一冊

この記事の内容と高い親和性が確認できたベストマッチです。早めにチェックしておきましょう。

開発環境のセットアップ

まず、Goの開発環境に加えて、Protocol Buffersコンパイラprotocと、Go用のgRPCプラグインをインストールします。

  1. Goのインストール: go.dev からインストールします。
  2. Protocol Buffersコンパイラのインストール: リリースページから、お使いのOSに合ったprotocをダウンロードし、パスの通ったディレクトリに配置します。
  3. Goプラグインのインストール:
    go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
    インストール後、$GOPATH/bin(または$HOME/go/bin)にパスが通っていることを確認してください。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

ステップ1:.protoファイルでサービスを定義する

プロジェクトのルートにprotoディレクトリを作成し、その中にuser.protoというファイルを作成します。このファイルに、サービスのインターフェースを定義します。

// proto/user.proto
syntax = "proto3";

package user;

option go_package = "example.com/grpc-go-guide/proto";

// ユーザーサービス
service UserService {
  // ユーザーIDを指定してユーザー情報を取得する
  rpc GetUser(GetUserRequest) returns (User);
}

// GetUserメソッドのリクエストメッセージ
message GetUserRequest {
  string user_id = 1;
}

// ユーザー情報を表すメッセージ
message User {
  string user_id = 1;
  string name = 2;
  int32 age = 3;
}
  • syntax = "proto3";: 使用するProtobufのバージョンを宣言します。
  • service UserService { ... }: UserServiceという名前のサービスを定義し、その中にGetUserというRPCメソッドを定義します。
  • message User { ... }: メソッドが使用するデータ構造をmessageとして定義します。各フィールドには型と、一意な番号(タグ)を割り当てます。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

ステップ2:Goのコードを自動生成する

次に、protocコマンドを使って、.protoファイルからGoのコードを自動生成します。

protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    proto/user.proto

このコマンドを実行すると、protoディレクトリ内に以下の2つのファイルが生成されます。

  • user.pb.go: UserGetUserRequestといったメッセージのGoの構造体と、シリアライズ/デシリアライズのためのコードが含まれます。
  • user_grpc.pb.go: UserServiceのインターフェースや、サーバーとクライアントのスタブコード(雛形)が含まれます。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

ステップ3:gRPCサーバーを実装する

自動生成されたコードを使って、gRPCサーバーを実装します。server/main.goを作成します。

// server/main.go
package main

import (
    "context"
    "log"
    "net"

    pb "example.com/grpc-go-guide/proto" // 生成されたコードをインポート
    "google.golang.org/grpc"
)

// user_grpc.pb.goで定義されたインターフェースを満たすための構造体
type server struct {
    pb.UnimplementedUserServiceServer
}

// GetUserメソッドの実装
func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.User, error) {
    log.Printf("Received request for user: %s", req.GetUserId())

    // 本来はデータベースなどからユーザー情報を取得する
    // ここではダミーデータを返す
    if req.GetUserId() == "1" {
        return &pb.User{UserId: "1", Name: "Alice", Age: 30}, nil
    }

    return nil, status.Errorf(codes.NotFound, "User not found")
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }

    // 新しいgRPCサーバーを作成
    s := grpc.NewServer()
    // サーバーにサービスを登録
    pb.RegisterUserServiceServer(s, &server{})

    log.Printf("server listening at %v", lis.Addr())
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}
  • pb.UnimplementedUserServiceServerを埋め込むことで、前方互換性を保ちつつ、実装したいメソッドだけを定義できます。
  • GetUserメソッドは、リクエストを受け取り、*pb.Usererrorを返します。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

ステップ4:gRPCクライアントを実装してサーバーと通信する

最後に、このサーバーにリクエストを送信するクライアントを実装します。client/main.goを作成します。

// client/main.go
package main

import (
    "context"
    "log"
    "time"

    pb "example.com/grpc-go-guide/proto"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
)

func main() {
    // サーバーへの接続を確立
    conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()

    // 新しいクライアントスタブを作成
    c := pb.NewUserServiceClient(conn)

    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    // GetUserメソッドを呼び出す
    r, err := c.GetUser(ctx, &pb.GetUserRequest{UserId: "1"})
    if err != nil {
        log.Fatalf("could not get user: %v", err)
    }

    log.Printf("User Info: ID=%s, Name=%s, Age=%d", r.GetUserId(), r.GetName(), r.GetAge())
}
  • grpc.Dialでサーバーへの接続を作成します。ここでは簡単のため暗号化なし(insecure)で接続しています。
  • pb.NewUserServiceClient(conn)で、サーバーのメソッドを呼び出すためのクライアントを取得します。
  • あとは、ローカルの関数を呼び出すかのようにc.GetUser(...)を実行するだけです。

まずサーバー(go run server/main.go)を起動し、次に別のターミナルでクライアント(go run client/main.go)を実行すると、クライアントのログにユーザー情報が表示され、サーバーのログにリクエスト受信のメッセージが表示されるはずです。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

まとめ:マイクロサービス通信の強力な選択肢

本記事では、GoとgRPCを使って、サービスを定義し、サーバーとクライアントを実装する一連の流れを解説しました。

  • .protoファイルでスキーマを最初に定義する「スキーマファースト」な開発により、堅牢なAPIを構築できる。
  • コード自動生成により、面倒なボイラープレートコードの記述から解放される。
  • HTTP/2とProtocol Buffersの恩恵により、高速で効率的な通信が実現できる。

gRPCは、特に内部のマイクロサービス間通信のように、パフォーマンスと信頼性が重視される場面でその真価を発揮します。Go言語のシンプルさとパフォーマンスはgRPCと非常に相性が良く、スケーラブルな分散システムを構築するための強力な基盤となります。

さらに理解を深める参考書

関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。

この記事をシェア

続けて読みたい記事

編集部がピックアップした関連記事で学びを広げましょう。

#Microservices

マイクロサービス vs モノリス 再入門【2025年版】:結局どちらを選ぶべきか?

2025/9/3
#AIOps

AIOps実践入門:PrometheusとGrafana連携によるAI駆動型モニタリング【2025年版】

2025/9/19
#Java

【2025年完全版】Spring Boot入門:初心者から実務レベルまで完全習得ガイド

2025/11/28
#マイクロサービス

マイクロサービスセキュリティ完全トラブルシューティングガイド【2025年実務脆弱性対策決定版】

2025/8/19
#Go

GoとGinによるハイパフォーマンスAPIサーバー構築ガイド【2025年版】

2025/9/19
#Flutter

【2025年完全版】Flutter状態管理ガイド:Provider、Riverpod、BLoC完全比較と実践

2025/11/28