Sébastien TIMONER
Web開発と技術チーム管理のエキスパートとして、高性能なデジタルソリューションの作成と最適化を専門としています。React.js、Node.js、TypeScript、Symfony、Docker、そしてFrankenPHPなどの最新技術における豊富な専門知識を活かし、様々な業界の企業向けに、設計から本番環境までの複雑なSaaSプロジェクトの成功を確実にします。
どこに行ってもCQRSの話題を耳にするのに、SymfonyやLaravelを引っ張り出さずにどう適用すればいいのか悩んでいませんか?朗報です。バニラPHPだけでCommand Query Responsibility Segregationを試すことができます。必要なのは明確なフォルダー構成と少しのクラスだけ。エディタを開いて、一緒に基礎を固めましょう。
php -v
でバージョンを確認し、readonly
プロパティ、厳格な型、First-Class Callableを活用しましょう。php -S 127.0.0.1:8000 -t public
で十分)。もし古いバージョンを使う必要がある場合は、ここで利用している機能(コンストラクタプロモーション、readonly
プロパティなど)が利用できるか確認し、必要に応じてサンプルコードを調整してください。
CQRSは**読み取り(Query)と書き込み(Command)**を分離する考え方です。これにより、2つの最適化された経路が得られます。
この分離はDDDの思想から自然に導かれますが、厳密な形式ばらずとも取り入れられます。すぐに得られるメリットは以下のとおりです。
ただしCQRSは構造上の複雑さを少し追加します。単純なCRUDであれば重すぎるかもしれません。ビジネスルールやスケール要件がそれを必要とするときに使いましょう。
シンプルな構成で十分です。
src/
Domain/
Article.php
ArticleRepository.php
Application/
Command/
CreateArticle/
CreateArticleCommand.php
CreateArticleHandler.php
Query/
ListArticles/
ListArticlesQuery.php
ListArticlesHandler.php
Bus/
CommandBus.php
QueryBus.php
Infrastructure/
InMemoryArticleRepository.php
public/
index.php
Domain(ビジネスルール)、Application(ユースケース)、Infrastructure(具体的な実装)を明確に分けます。
Article
アグリゲートとリポジトリを定義します。
php
php
コマンドは意図を運びます。ハンドラーはビジネスロジックを調整します。
php
php
重要な注意点:ハンドラーは何も返しません。記事を再取得したい場合はクエリ経由で行います。
php
php
プレゼンテーション層をドメインモデルに結び付けず、直列化しやすい配列を返します。
php
この実装は後でDoctrineやPDO、外部APIに差し替えてもハンドラーを触る必要はありません。
ハンドラー解決を中央集約するとCQRSの良さが際立ちます。
php
php
これらのバスは素朴ですが、仕組みを理解するには十分です。実案件ではPHP-DIやSymfony DIなどのDIコンテナに接続するのも良いでしょう。
public/index.php
でのブートストラップ例php
(...)
演算子(First-Class Callable)はPHP 8.1から利用でき、PHP 8.4でも完全にサポートされています。より古いバージョン(8.0以下)を対象にする場合は、fn ($command) => $createHandler($command)
のように書き換えてください。
基盤ができたら、次のステップに進めます。
ArticlePublished
を発火し、別レイヤーで処理する。この骨組みがあれば、既存プロジェクトに段階的にCQRSを導入したり、フレームワークなしで新しいサービスを立ち上げたりできます。読み取りと書き込みの境界を明確に保ち、アーキテクチャを反復的に育てていきましょう。楽しい実験を!