CQRS(読み/書き分離)詳細アウトライン:全37章 😺📚✨
第1章 CQRSってなに?まずは“絵”で理解しよ🎨
-
ねらい:CQRS=「読む」と「書く」を分ける考え方👀✍️
-
学ぶこと:Command / Query の超ざっくり定義
-
ミニ演習:身近な例(SNS・EC・ToDo)で「読む」「書く」を分けて書く📝
-
AIプロンプト例:
- 「CQRSを中学生にもわかる例で説明して」🤖
第2章 CQRSが効く場面・やめとく場面⚖️
- ねらい:やらない勇気も含めて判断できるようにする🫶
- 学ぶこと:検索が重い/集計が多い/整合性が厳しい などのサイン
- ミニ演習:「この機能はCQRS向き?」チェックリスト作成✅
- AI:要件を貼って「CQRS必要度」を点数化させる🤖📊
第3章 用語を先に“辞書化”して迷子防止🧭
- 学ぶこと:Handler / DTO / ReadModel / WriteModel / Projection
- ミニ演習:用語カード(1行説明)を作る🗂️
- AI:1行説明を作らせて自分の言葉に直す✍️🤖
第4章 環境準備(Windows + VS 2026)🧰
- 学ぶこと:.NET 10 / C# 14 前提でプロジェクト作成(Microsoft Learn)
- ミニ演習:最小Web API起動まで🎯
- AI:READMEに「セットアップ手順」を書かせる🤖📄
第5章 題材決め(ミニEC / ToDo)と“要件の作り方”🛒✅
- 学ぶこと:CQRSが活きるように「検索要件」を少し入れるコツ🔍
- ミニ演習:ユーザーストーリーを5個作る📝
- AI:ユーザーストーリー案を量産→良いのだけ採用🤖✨
第6章 あえて“混ぜた実装”を作ってツラさ体験😵💫
- 学ぶこと:読み書き混在の悪さ(変更が怖い、テストしにくい)
- ミニ演習:1つのServiceに全部入れて、後で苦しむ😇
- AI:改善点レビューをAIにさせる→自分で採点🧑🏫🤖
第7章 前段のCQS(更新と参照を同じ関数に混ぜない)✂️
- 学ぶこと:Queryは副作用なし、Commandは状態変更あり
- ミニ演習:メソッドをCommand/Queryに分類する🔍
- つまずき:更新しつつ戻り値で色々返したくなる問題😅
第8章 ライトCQRSの最小形① DTOを分ける📦
- 学ぶこと:CreateXxxCommand / GetXxxQuery の“形”
- ミニ演習:DTOをrecordで作る🧩
- AI:DTO雛形生成→命名を整える🤖🧹
第9章 ライトCQRSの最小形② Handlerを分ける🧑🍳
- 学ぶこと:CommandHandler / QueryHandler の責務
- ミニ演習:1機能だけHandler化してControllerから呼ぶ📮
- つまずき:Handlerが肥大化しがち🍔→「1ユースケース=1Handler」目安
第10章 プロジェクト構成(フォルダ・命名・責務)📁
- 学ぶこと:迷わないルール作り(例:Features/Orders/Commands…)
- ミニ演習:命名規約を決めてREADMEへ🏷️
- AI:命名規約のドラフト生成🤖
第11章 Commandの基本① “戻り値を欲張らない”✍️
- 学ぶこと:Commandは「成功/失敗 + IDくらい」でOK
- ミニ演習:Createの戻り値を最小にする✅
- つまずき:Queryみたいに全部返したくなる問題😅
第12章 Commandの基本② Validationの分離(入口で守る)🔍
- 学ぶこと:UI検証 / 仕様検証 / 業務ルール の違い
- ミニ演習:チェックを3分類(必須/範囲/状態依存)🗂️
- AI:検証ルール一覧を作らせる→過不足を調整🤖
第13章 Commandの基本③ 業務ルールの置き場所🏛️
- 学ぶこと:業務ルールはCommand側(ドメイン寄り)へ
- ミニ演習:「在庫不足」「期限切れ」等をCommand側で表現
- つまずき:画面都合の分岐を混ぜる問題📺💦
第14章 Write側DBアクセス① EF Coreで“更新”を通す🧱
- 学ぶこと:Writeは整合性重視(追跡・変更管理が便利)
- ミニ演習:Create/Update/Delete をEFで実装
- AI:EFのベースコード生成→例外処理を自分で整える🤖🛠️
第15章 Write側DBアクセス② トランザクション感覚🛡️
- 学ぶこと:1回の更新で守る範囲(ざっくりでOK)
- ミニ演習:2つ更新が必要なケースをトランザクションで守る🔒
- つまずき:何でも同時に更新したくなる欲張り問題😇
第16章 Write側DBアクセス③ 競合(同時更新)と楽しい現実💥
- 学ぶこと:楽観的同時実行(ざっくり理解でOK)
- ミニ演習:同時更新で壊れる→検知する🧯
- AI:競合時メッセージ案を作らせる🤖💬
第17章 Queryの基本① Read DTO(表示用モデル)を作る👀
- 学ぶこと:Read DTOは“画面に都合の良い形”でOK📄
- ミニ演習:一覧用DTO(ListItem)を設計
- つまずき:Writeモデルをそのまま返しがち問題😅
第18章 Queryの基本② EFで投影&AsNoTrackingで軽量化⚡
- 学ぶこと:追跡しない、必要列だけ取る
- ミニ演習:DTO投影でクエリを軽くする🚀
- AI:LINQの投影コードを提案させる🤖
第19章 Queryの基本③ ページング/ソート/フィルタの定番セット📄✨
- 学ぶこと:検索条件DTO、ページングの基本
- ミニ演習:ページング + ソートを入れる📑
- つまずき:全件取得してから絞る問題🐢
第20章 Queryの発展① Dapper/生SQLの入口(必要になったら)🧪
- 学ぶこと:複雑検索はSQLが強いことも(でも最初は“選択肢”)
- ミニ演習:同じ一覧をEF版/SQL版で比べる🔁
- 注意:最初から全部Dapperにしない(疲れる)😇
第21章 Queryの発展② 集計・検索の“読みモデル設計”📊
- 学ぶこと:表示に必要な形へ寄せる(JOIN/集計/派生列)
- ミニ演習:一覧に「件数」「合計」などを追加
- AI:SQL案を出させて、危険(N+1等)を指摘させる🤖⚠️
第22章 API層は薄く① Controller/Minimal APIの作法🔌
- 学ぶこと:APIは「受け取って投げる」係📮
- ミニ演習:Controllerを薄くする(if減らす)🧼
- つまずき:Controllerが神クラス化👑💦
第23章 API層は薄く② 入力→DTO→Handlerの流れを固定する🧩
- 学ぶこと:毎回同じ型で迷いを減らす
- ミニ演習:Create/Update/GetList の3本をテンプレ化
- AI:テンプレ生成→自分で“責務”チェック👀🤖
第24章 Dispatcherを自作して“仕組み”を理解📬
- 学ぶこと:小さなMediator(Dispatcher)を作る
- ミニ演習:ICommandHandler / IQueryHandler を定義
- つまずき:汎用化しすぎて迷路化🌀→最小で!
第25章 MediatR導入は“後でOK”(採用判断)🎒
- 学ぶこと:導入メリット(パイプライン/責務分離)とコスト
- ミニ演習:自作Dispatcherと比較メモ📝
- 注意:ライセンスや配布元の確認は必ず🔍(現場ルールに従う)(Jimmy Bogard)
第26章 横断関心① Logging(Command/Queryの開始・終了を揃える)🧾
- 学ぶこと:どこでログを取るか(入口で統一)
- ミニ演習:成功/失敗/所要時間をログに出す⏱️
- AI:ログメッセージ案を作らせて整える🤖
第27章 横断関心② エラー設計(業務エラー vs 技術エラー)🧯
- 学ぶこと:例外を暴れさせない分類
- ミニ演習:在庫不足(業務)/DB落ち(技術)を分けて返す
- つまずき:全部Exceptionで握りつぶす問題🙈
第28章 横断関心③ Validationを共通化(やりすぎ注意)🔍
- 学ぶこと:共通化の境界(DRYの誤爆を防ぐ)
- ミニ演習:共通バリデーション1つだけ作る
- AI:過剰抽象化を指摘させる🤖⚠️
第29章 テスト① Commandは単体テストが主役🧪✨
- 学ぶこと:Command=ルールの塊→単体テスト向き
- ミニ演習:Commandテストを3本だけ書く(最小でOK)
- AI:テストケース案を出させて取捨選択🤖✅
第30章 テスト② Queryは統合寄り(現実路線)🧫
- 学ぶこと:SQL/LINQ絡むので統合テストが相性良い
- ミニ演習:一覧クエリのスモークテスト
- つまずき:Queryを単体テストで頑張りすぎる問題😵
第31章 パフォーマンス① “計測してから直す”📏⚡
- 学ぶこと:体感じゃなく計測(時間・回数・件数)
- ミニ演習:遅いクエリを1つ見つける🔍
- AI:改善案を出させて、必ず計測で答え合わせ🤖📊
第32章 パフォーマンス② インデックスとN+1の超基本📌
- 学ぶこと:読みのボトルネックあるある(N+1、全件取得)
- ミニ演習:N+1を再現→直す🔧
- AI:原因推理をさせて自分で確認🕵️🤖
第33章 パフォーマンス③ キャッシュ入門(最初は軽く)🧊
- 学ぶこと:キャッシュの“使いどころ”と“事故りどころ”
- ミニ演習:読み一覧に短時間キャッシュ(失効も体験)
- 注意:キャッシュは万能じゃない😇
第34章 Readモデル分離① “別テーブル”の発想(Projection入門)🪞
- 学ぶこと:Read専用テーブル(検索最適化)の意味
- ミニ演習:OrderList用の集計テーブルを作る📊
- つまずき:Writeと同じ形で作ってメリットが出ない問題💦
第35章 Readモデル分離② 最終的整合性(ゆるく体験)⏳
- 学ぶこと:「反映がちょい遅れる」世界観
- ミニ演習:反映遅延がある前提のUI文言を考える🗣️
- AI:UX文言案を作らせて選ぶ🤖💬
第36章 Readモデル分離③ 冪等性(2回走っても壊れない)🔁🧱
- 学ぶこと:二重送信/再実行に強くする発想
- ミニ演習:同じ更新を2回投げても壊れないようにする
- つまずき:部分成功が残って壊れる問題😱
第37章 仕上げ(セキュリティ & API契約 & 卒業課題)🎓🔐✨
-
学ぶこと:
- Queryで漏らしがちな情報(権限・フィルタ)🔐
- APIの互換性(壊さず進化)🧷
- 次の発展:Outbox / Saga / CQRS+イベント(必要になったら)🚀
-
卒業課題:
- 「検索が重い画面」をRead最適化して、改善前後の計測レポを書く📈✍️
-
AI:
- 「セキュリティ観点の抜け漏れチェックして」
- 「互換性を壊さない変更案を提案して」🤖✅