Skip to content

Latest commit

 

History

History
211 lines (160 loc) · 6.5 KB

File metadata and controls

211 lines (160 loc) · 6.5 KB

CQRS/Event Sourcing Example PHP プロジェクト

このプロジェクトは、PHPでCQRS(Command Query Responsibility Segregation)とEvent Sourcingの実装例を示すプロジェクトです。

プロジェクト概要

開発環境構築

Docker環境

すべてのコマンドはDockerコンテナ内で実行してください。

# コンテナ起動
make docker-compose-build
make docker-compose-up

# コンテナ停止
make docker-compose-down

# アプリケーションコンテナ内でのコマンド実行
docker compose exec app [コマンド]

開発規約

コードフォーマット・静的解析

# コードフォーマット
make fmt

# 静的解析
make phpstan

# リント(フォーマット + 静的解析)
make lint

テスト実行

# 全テスト実行
docker compose exec app composer test

# カバレッジ付きテスト
docker compose exec app composer test:coverage

# 特定のテストファイル実行
docker compose exec app vendor/bin/phpunit tests/Path/To/TestFile.php --testdox

命名規則

  • 変数名: スネークケース(snake_case)を使用
  • クラス名: パスカルケース(PascalCase)
  • メソッド名: キャメルケース(camelCase)
// Good
$group_chat_id = new GroupChatId();
$user_account = $this->findUserAccount($user_id);

// Bad
$groupChatId = new GroupChatId();
$userAccount = $this->findUserAccount($userId);

TDD(Test Driven Development)

新機能実装時は必ずRed-Green-Refactorサイクルに従ってください。

  1. Red: テストを先に書いてfailすることを確認
  2. Green: テストが通る最小限のコードを実装
  3. Refactor: 必要に応じてコードを改善

データプロバイダーのテスト規約

/**
 * @dataProvider testMethodNameProvider
 */
public function testMethodName(...): void {
    // テスト実装
}

// データプロバイダーメソッドはテストメソッドの直下に配置
public function testMethodNameProvider(): array {
    return [
        'case name' => [
            // テストデータ
        ],
    ];
}

アーキテクチャ

CQRS原則

  • Command側: データの変更(Mutation)のみ
  • Query側: データの読み取り(Query)のみ

ディレクトリ構造

.
├── src/
│   ├── Command/              # Command側(書き込み)
│   │   ├── Domain/          # ドメインロジック
│   │   ├── InterfaceAdaptor/ # GraphQL Mutation、Repository実装
│   │   └── Processor/       # コマンド処理
│   ├── Query/               # Query側(読み取り)
│   │   ├── Domain/          # ReadModel定義
│   │   └── InterfaceAdaptor/ # GraphQL Query、Repository実装
│   └── Rmu/                 # Read Model Updater(イベントハンドラー、DAO)
├── public/                  # APIエンドポイント
│   ├── read-api-server.php  # Query側GraphQL APIサーバー
│   └── write-api-server.php # Command側GraphQL APIサーバー
└── bin/                     # CLIツール
    └── read-model-updater-streams.php # RMUプロセス

エンドポイント

プロジェクトには2つのGraphQL APIエンドポイントがあります:

  • Write API (http://localhost:18080): Command側(Mutation)

    • エンドポイント: /query
    • GraphQL Playground: /
    • 実装: public/write-api-server.php
  • Read API (http://localhost:18000): Query側(Query)

    • エンドポイント: /query
    • GraphQL Playground: /
    • 実装: public/read-api-server.php

GraphQL実装

  • Command側: MutationResolverを実装
  • Query側: QueryResolverを実装済み
// Command側のMutationResolver例
public function createGroupChat(mixed $root_value, array $args): array {
    // バリデーション
    if (!is_string($args['name'])) {
        throw new \InvalidArgumentException('Name must be a string');
    }

    // ドメインロジック実行
    $event = $this->command_processor->createGroupChat($name, $executor_id);

    return $result;
}

// Query側のQueryResolver例
public function getGroupChats(mixed $root_value, array $args): array {
    // リポジトリから読み取り専用データを取得
    return $this->group_chat_query_repository->findAll();
}

Read Model Updater (RMU)

RMUはDynamoDB Streamsからイベントを読み取り、Query側のReadModelを更新するプロセスです。

  • 実装: bin/read-model-updater-streams.php
  • 動作: DynamoDB StreamsからイベントをポーリングしてMySQLのReadModelを更新
  • イベントハンドラー:
    • GroupChatCreatedEventHandler
    • GroupChatRenamedEventHandler
    • GroupChatDeletedEventHandler
    • GroupChatMemberAddedEventHandler
    • GroupChatMemberRemovedEventHandler
    • GroupChatMessagePostedEventHandler
    • GroupChatMessageEditedEventHandler
    • GroupChatMessageDeletedEventHandler

プルリクエスト作成時の注意事項

  • 言語: タイトルと本文は日本語で記述する
  • コミットメッセージ: "by Claude Code" を含める
  • テンプレート: .github/PULL_REQUEST_TEMPLATE.md があれば使用する
  • チェック項目:
    • 全テストが通ることを確認
    • PHPStanエラーがないことを確認
    • コードフォーマットを適用済み
    • 関連するテストを追加・修正した場合のみチェック

利用可能なComposerスクリプト

composer test        # テスト実行
composer test:coverage # カバレッジ付きテスト
composer cs          # コードスタイルチェック(dry-run)
composer cs:fix      # コードフォーマット実行
composer fmt         # cs:fixのエイリアス
composer lint        # cs + phpstan
composer phpstan     # 静的解析

参考リンク