このリポジトリは、Go言語でgRPCマイクロサービスを実装する実践的なプロジェクトです。CQRS(Command Query Responsibility Segregation)パターンを採用し、商品管理システムを題材としたマイクロサービスアーキテクチャを学習できます。
- gRPCを使用したマイクロサービスの実装方法を学習
- CQRSパターンによる読み取り・書き込み責務の分離
- Protocol Buffersによるスキーマファーストな開発
- 実用的なAPIバリデーションとエラーハンドリング
- 商品管理: 商品のCRUD操作とカテゴリ管理
- Command Service: 書き込み専用サービス(作成、更新、削除)
- Query Service: 読み取り専用サービス(一覧取得、詳細取得、キーワード検索)
- Client Service: REST APIを提供するフロントエンドサービス(Swagger UI付き)
- スキーマバリデーション: protovalidateによるフィールドレベル検証
.
├── api/ # API定義・生成コード
│ ├── proto/ # Protocol Buffers定義
│ └── gen/ # 自動生成コード
│
├── k8s/ # Kubernetesマニフェスト
│ ├── base/ # 共通マニフェスト
│ └── overlays/ # 環境別オーバーレイ
│
├── service/ # マイクロサービス実装
│ ├── client/ # REST APIクライアント(Swagger UI付き)
│ ├── command/ # コマンドサービス(書き込み専用)
│ └── query/ # クエリサービス(読み取り専用)
│
├── db/ # データベース関連
│ ├── command/ # コマンド用データベース
│ ├── query/ # クエリ用データベース
│ └── logs/ # データベースログ
│
└── pkg/ # 共通ライブラリ
└── connect/interceptor/ # Connect RPC向けのロギング/バリデーション共通インターセプター
このプロジェクトは**CQRS(Command Query Responsibility Segregation)**パターンを採用しています:
graph TB
subgraph "Client Applications"
Browser[Browser]
CLI[CLI Tool]
end
subgraph "REST API Layer"
Client[Client Service<br/>REST API + Swagger<br/>:8080]
end
subgraph "gRPC Services"
subgraph "Command Side (書き込み)"
CS[Command Service<br/>gRPC<br/>:50051]
CDB[(Command DB<br/>Write Optimized)]
end
subgraph "Query Side (読み取り)"
QS[Query Service<br/>gRPC<br/>:50052]
QDB[(Query DB<br/>Read Optimized)]
end
end
Browser -->|HTTP/REST| Client
CLI -->|HTTP/REST| Client
Client -->|Connect RPC| CS
Client -->|Connect RPC| QS
CS --> CDB
QS --> QDB
CDB -.->|Replication| QDB
classDef clientService fill:#f9f,stroke:#333,stroke-width:2px
classDef commandService fill:#fff3e0
classDef queryService fill:#e1f5fe
classDef database fill:#e8f5e8
classDef client fill:#f3e5f5
class Client clientService
class CS commandService
class QS queryService
class CDB,QDB database
class Browser,CLI client
- 3層アーキテクチャ: Client Service(REST) → Command/Query Service(gRPC) → Database
- 責務の分離: 読み取りと書き込みを独立したサービスに分離
- REST + gRPC: クライアント向けREST API、サービス間通信はgRPC
- スケーラビリティ: 各サービスを独立してスケール可能
- データベース最適化: 用途に応じたデータベース設計
- 型安全性: Protocol Buffersによる厳密な型定義
- 構造化ログ: slogによるコンテキスト対応の構造化ログ
- 依存性注入: Uber Fxによる型安全な依存関係管理
- 共通Connectインターセプター: slogロギングとProtovalidate検証を共通パッケージで提供
各サービスは config.toml で設定を管理します:
[log]
level = "info" # ログレベル: debug, info, warn, error
format = "text" # ログフォーマット: text, json
[mysql]
dbname = "command_db"
host = "localhost"
port = 3306
user = "root"
pass = "password"
max_idle_conns = 10
max_open_conns = 100
conn_max_lifetime = "1h"
conn_max_idle_time = "10m"環境変数で設定を上書き可能:
LOG_LEVEL,LOG_FORMAT: ログ設定DB_HOST,DB_PORT,DB_USER,DB_PASS: データベース設定
# リポジトリのクローン
git clone https://github.com/haru-256/practical-go-grpc-micro-service.git
cd practical-go-grpc-micro-service
# 開発環境のセットアップ
mise install
# APIコードの生成
cd api
make generate
# 依存関係の解決
cd ..
go mod tidy# すべてのサービス(データベース+アプリケーション)を起動
docker compose up -d --build
# サービスの起動確認
docker compose ps
# Client Service(API Gateway)にアクセス
# Swagger UIでAPIを確認
open http://localhost:8090/swagger/index.html
# ログの確認
docker compose logs -f client_service
# サービスの停止
docker compose down
# データベースも含めて完全削除
docker compose down -vポートマッピング:
- Client Service (REST API):
http://localhost:8090 - Command Service (gRPC):
http://localhost:8083 - Query Service (gRPC):
http://localhost:8085 - Command DB (MySQL):
localhost:3306 - Query DB (MySQL):
localhost:3307 - phpMyAdmin:
http://localhost:3100
初回起動時の注意:
Docker Composeで起動すると、データベースは自動的に作成されますが、CQRSパターンのレプリケーション設定は手動で行う必要があります。詳細は Database README を参照してください。
# データベースのレプリケーション設定
cd db
make create-data # テストデータ作成
make dump # Command DBをダンプ
make restore # Query DBにリストア
make start-replication # レプリケーション開始開発時はローカルでサービスを起動することもできます:
# データベースのみ起動
docker compose up -d command_db query_db db_admin
# コマンドサービス(ポート8083)
cd service/command
go run cmd/server/main.go
# クエリサービス(ポート8085)
cd service/query
go run cmd/server/main.go
# クライアントサービス(ポート8090)- Command/Queryサービスが必要
cd service/client
go run cmd/server/main.go# すべてのテストを実行
make test
# Command Serviceのテスト
cd service/command
make test
# Query Serviceのテスト
cd service/query
make test
# Client Serviceのテスト
cd service/client
go test ./...
# 統合テストを含む(データベースが必要)
cd service/command
go test -tags=integration ./...
cd service/query
go test -tags=integration ./...このプロジェクトでは、Kustomize を使用してKubernetesマニフェストを管理しています。
k8s/base/: 全ての環境で共通のベースとなるマニフェストnamespace.yaml: プロジェクト用の名前空間db/: データベース関連のマニフェストservices/: 各マイクロサービスのマニフェスト
k8s/overlays/dev/:dev環境用の差分マニフェスト(例: リソース割り当て、レプリカ数など)
Kustomizeを使用して、特定の環境(例: dev)にデプロイするには、以下のコマンドを実行します。
# dev環境のマニフェストを適用
kubectl apply -k k8s/overlays/devこれにより、baseのマニフェストとdevオーバーレイが結合されたマニフェストがクラスターに適用されます。
api/proto/でProtocol Buffersファイルを編集cd api && make generateでコード生成go mod tidyで依存関係更新- サービス実装を更新
db/command/ddl/またはdb/query/ddl/でDDLを編集cd db && make resetでデータベースリセット- 新しいスキーマでサービスを再起動
- Client Service - REST APIサービスの実装詳細(Swagger付き)
- Command Service - 書き込み専用サービスの実装詳細
- Query Service - 読み取り専用サービスの実装詳細
- API仕様書 - 詳細なAPI仕様とサンプル
- データベース設計 - DB設計とCQRS実装
- プロジェクトスタイルガイド - コーディング規約と設計原則
- Issueで問題を報告または新機能を提案
- フィーチャーブランチを作成
- 変更をコミット(コミットメッセージはConventional Commitsに従う)
- プルリクエストを作成
このプロジェクトはMITライセンスの下で公開されています。