タラバガニー設計局stalins.clubNOTE/notes/command-bus

Command BusはOperation dispatchの選択肢でありArchitectureの前提ではない

Command Busは、Commandのtypeから対応するhandlerを選び、実行をdispatchする仕組みである。Mediator patternとしてprocess内で実装することも、message brokerを介して非同期化することもできるが、この2つは運用特性が大きく異なる。

典型的には次のような形になる。

HTTP / MCP / Job
      ↓
   Command Bus
      ↓
 Command Handler
      ↓
 Domain / Repository

Busを置く利点は、validation、authorization、transaction、telemetry、idempotencyなどのcross-cutting behaviorをdispatch pipelineへ集約しやすいことにある。またcallerがhandler実装を直接知らず、Commandのcontractへ依存できる。

しかし、複数Transportを支えるためにCommand Busが必須になるわけではない。Microsoftの.NET application-layer guidanceでも、controllerからcommand handlerを直接呼ぶ構成、in-memory mediatorを使う構成、非同期queueを使う構成はいずれも選択肢として扱われている。Transport Adapterが共通のOperationはTransportから独立したApplication Capabilityとして置ける を直接呼べるなら、それだけでHTTP/MCP/Job間のlogic共有は成立する。

BusにはLocalization CostはLayerと抽象化を増やすほど無視できなくなる という反対側のコストがある。dynamic registrationやmiddleware pipelineが増えると、call siteから実際のhandler・authorization・transaction boundaryを静的に追いにくい。人間にもAI coding agentにも「このCommandは結局どこで実行されるか」を探索するhopが増える。

したがってCommand Busは、

  • 共通pipeline behaviorが十分に増えた
  • dispatchを一級の拡張点にしたい
  • queueing/retryなどrequest lifecycleをCommand単位で扱いたい

といった要求が出たときに導入する方がよい。単に「CleanなArchitectureに見えるから」という理由で全OperationをBus経由にする必要はない。

またCQRSはRead ModelとWrite Modelの分離でありCommand BusやEvent Sourcingの同義語ではない とも同義ではない。CQRSはread/write modelの分離であり、Command Busはdispatch mechanismである。

出典

▸ ノート一覧に戻る