設計ナイト2020
https://kichijojipm.connpass.com/event/191220/
に参加してきたので、そのときのレポート
正直、設計に関して疎くて内容の 1 割くらいしか分からなかったのでメモ程度です。
かとじゅんさん発表
資料
https://speakerdeck.com/j5ik2o/event-sourcingwojie-shuo-suru
今日は、分散システムの設計パターンの話をします。
CQRS の話
DDD によるクエリサイドのペインについて
- クエリ要件を満たすことでリポジトリが複雑になる
- レスポンス用 DTO をリポジトリで組み立てるため、N + 1 クエリが発生しやすい
- ドメインオブジェクトから DTO への変換が非効率
※これらのペインを飲み込めるのであれば、CQRS を採用する必要はない。
CQRS とは
リポジトリがステートを書くのではなく、イベントを書く
イベントをどう使うのか?
イベントというのは、そのとき起こったできごとを保持している
e.g. カートが作られたとか、誰が作ったとか。
そういうのが、git の commit log のようにどんどん溜まっていく
その歴史が大量になってくると、apply する等のときにコストが大きくなる。
イベントソーシングでない CRUD の場合はレイテンシが悪化しやすい。
なぜ C/Q を分けるのか?
一貫性/可用性
この表でも分かるように、扱いが違う
スケーラビリティ
コマンド
一般的な web サービスだと、write よりも read のほうが多い
CQRS の利点と欠点
利点
- 最悪 write 系が落ちていても read 系が生きていれば、障害にならない。
- 障害点が分離できる
- コマンドとクエリを別々にスケールできる。
欠点
- コストがかかる
- 構成要素が多くなる
- CQRS は複雑と言われることが多いが、従来モデルよりもある意味シンプルになる
CQRS でモデルがどう変わるか?
CQRS では、ドメインオブジェクトはドメインロジックを実行するためのシンプルなモデルとなる
ただし、全体の構造は複雑になる
非Event Sourcing での CQRS は色々難しい
CQRS/ES 対応分散システムフレームワーク
- Akka
- Akka.NET
- proto.actor
- リアクティブシステムが作れそうなのは Golang のみ
境界を引かない=非 CQRS にする
コストをかけてまで恩恵を受けられる想定がないのではれば
CQRS を避けるのも手段としてはあり。
Q & A
Q.
境界を引かない方法って、CQが混じった方法とどこが違うんでしょうか?
A.
極端な話すると、リポジトリをクエリ側で使わないようにする状態のこと
CQRS を使わない方針に倒したほうがいいということ
大まかな C/Q の役割はあるんだけど、明確に分けなくていいよということ
qsonaさん発表
資料
https://hackmd.io/@jnl1y8gDTkq7ywsLXpa6GQ/HkDGObSOP
GraphQL を利用したアプリケーションの設計パターンの話
GraphQL とは
web api を定義するための言語のようなもの
rest api の代わりになるようなもの
サーバー側では、1 つの目的に対して 1 つのエンドポイントがあるが
GraphQL ではエンドポイントは 1 つになる。
クライアントがクエリを宣言する = クライアントが自分で取得するデータを定義している
クライアントサイドの設計
リポジトリ層を作らない理由としては
GraphQL のメリットを殺してしまうから。
また、そもそもクライアントの read リポジトリは作りにくい。
Appllo Stack
colocation
子供のコンポーネントにも、GraphQL の フラグメントを持つ。
そうすると、親のコンポーネントが肥大化しなくて済む。
サーバーサイドの設計
rest api とそこまで変わらない。
Hasura
一言で言うと、PostgreSQL(など)のテーブル定義をするだけで GraphQL API が使える
Service to Service GraphQL
マイクロサービスとかやってると、サーバーで api 作ったけど
どこから使われてるから消しにくいみたいなことがある。
が、それを解決してくれる。