依存関係
モジュール間の依存方向と、依存関係を管理する理由を説明します。
依存方向の原則
client-apps → server-apps → server-core
↓
server-platform (実装注入)
基本ルール
- 一方向依存: 依存は一方向のみ。循環依存は禁止
- coreは独立: server-coreは他のモジュールに依存しない
- 実装注入: server-platformの実装はserver-appsから注入
各モジュールの依存関係
client-apps
- ✅ 依存可能: packages/*(共有パッケージ)
- ❌ 依存禁止: server-*(サーバーコードは直接参照しない)
理由: クライアントとサーバーは別リポジトリに分離する可能性があるため
server-apps
- ✅ 依存可能:
- server-core/*(ドメインサービス使用)
- server-platform/*(実装取得して注入)
- packages/proto-gen-go(gRPC型定義)
- ❌ 依存禁止: client-apps/*
理由: アプリケーション層は依存注入のコンポジションルート
server-core
- ✅ 依存可能: server-core内の他のパッケージ(例:shared)
- ❌ 依存禁止:
- server-platform/*(実装に依存しない)
- server-apps/*(アプリケーション層に依存しない)
- packages/proto-gen-*(Protobuf生成コードに依存しない)
理由: ドメイン層は技術的詳細から独立させる
server-platform
- ✅ 依存可能: server-core/*(ポートを実装するため)
- ❌ 依存禁止: server-apps/*(実行物に依存しない)
理由: 実装は差し替え可能にし、アプリケーション層に依存させない
依存方向の例
良い例:投稿作成フロー
// server-apps/gateway/handlers/post_handler.go
import (
"go.bazbii.app/core/post" // ✅ core使用
"go.bazbii.app/platform/datastore" // ✅ platform使用
)
// server-core/post/service.go
import (
. "go.bazbii.app/core/shared" // ✅ core内のみ
)
// server-platform/datastore/postgres/post_repository.go
import (
"go.bazbii.app/core/post" // ✅ coreのポート実装
)
悪い例:循環依存
// ❌ server-core/post/service.go
import "go.bazbii.app/platform/datastore" // 実装に依存してはいけない
// ❌ server-platform/datastore/postgres/post_repository.go
import "go.bazbii.app/platform/observability" // 他のplatformに依存してはいけない(必要ならcore経由)
Protocol Buffersの扱い
原則
- proto定義:
packages/proto/に配置 - 生成コード:
packages/proto-gen-go/,packages/proto-gen-ts/ - server-core: proto-gen-*を直接importしない
理由
- ドメイン層はプロトコルの詳細から独立させる
- コントラクト変更時の影響を最小化
実装例
// ❌ server-core/post/entity.go
import "go.bazbii.app/packages/proto-gen-go/bazbii/types/v1" // NG
// ✅ server-core/post/entity.go
type Post struct {
ID PostID
ActorID ActorID
H3Index H3Index // ドメイン型を使用
}
// ✅ server-apps/api/handlers/post_handler.go
// ここでproto型とドメイン型を変換
func (h *PostHandler) Create(ctx context.Context, req *pb.CreatePostRequest) (*pb.CreatePostResponse, error) {
// proto型 → ドメイン型
post, err := post.NewPostDraft(req.H3Index, req.Text, actorID)
// ドメイン型 → proto型
return &pb.CreatePostResponse{PostId: post.ID.String()}, nil
}
共有パッケージ (packages)
依存方向
全てのモジュール → packages/*
packages/* → packages/*(限定的)
packages/* → server-* or client-*(禁止)
配置すべきもの
- ✅ 設計: Protocol Buffers定義、型定義
- ✅ ユーティリティ: i18n, themes, ts-utils
- ❌ ビジネスロジック: packagesには置かない
依存関係の管理
Go Workspace
- 複数のGoモジュールを一つのワークスペースで管理
go.workで依存関係を管理
pnpm Workspace
- TypeScript/JavaScriptパッケージをワークスペースで管理
pnpm-workspace.yamlで設定
依存関係の確認方法
# Goモジュールの依存関係確認
cd server-core
go mod graph
# 循環依存チェック
go list -m all
# pnpmワークスペースの依存確認
pnpm list --depth=0