投稿日:2026/6/14
更新日:2026/6/14

CQRS(Command Query Responsibility Segregation)は、データを扱う処理を次の2種類に分ける考え方。
簡単にいえば、「見る処理」と「変える処理」を分ける。
// Query: ユーザー情報を見る
getUserQuery(userId);
// Command: ユーザー名を変える
updateUserNameCommand(userId, "田中");
Queryは原則としてデータを変更しない。
Commandは登録・更新・削除などを行う。
tRPCのqueryとmutationに近い。
export const userRouter = router({
get: procedure.query(async () => {
// Query: 取得
}),
update: procedure.mutation(async () => {
// Command: 更新
}),
});
| tRPC | CQRS | 役割 |
|---|---|---|
.query() |
Query | データの取得 |
.mutation() |
Command | 登録・更新・削除 |
ただし、CQRSではルーター上で分けるだけでなく、内部の処理もQueryとCommandとして明確に分離する。
getOrganizationQuery();
updateOrganizationCommand();
PR #2500では、取得と更新を次のように分けている。
getOrganizationQuery // 組織情報を取得する
updateOrganizationCommand // 組織情報を更新する
また、実装方法として次の2パターンを比較している。
通常のDI版では、処理に必要な値を先に渡し、実行時にDBを注入する。
const query = buildGetCertificationQuery({
organizationId,
certificationId,
});
return query.execute(ctx.prisma);
このPRの主な結論は、今回のような単純な取得・部分更新では、Effect-tsより通常のDIのほうが薄く読みやすいというもの。
CQRSには、読み取り用と書き込み用でDBやデータモデルまで分ける高度な構成もある。
PR #2500はそこまで行わず、まずコード上で取得処理をQuery、変更処理をCommandに分けた比較用デモとなっている。
CQRSは、データを「見る処理」と「変える処理」に分ける設計。