マイクロフロントエンドとキャッシュを前提としたCQSアーキテクチャを考える
#設計 #CQS #アーキテクチャ
#WIP #思考実験
大前提:
要求分析
システムの振る舞いを設計する際はコトに着眼する
オーナーシップを持てない方はアーキテクチャを決めるべきでない
マイクロフロントエンドとCQS, CQRSについて考える
追記: 後から知ったけれども、Hasuraでは3factor appと言われるアーキテクチャらしい
文脈
リアクティブやメッセージング要件の重要度が高いシステム
分散型アーキテクチャ,サービス指向アーキテクチャ指向
境界づけられたコンテキストでのマイクロフロントエンド
キーポイント
Immutable Model
イベント駆動
persistence ignorant
遅延結合と遅延初期化とリソース更新/破棄の自動化
BaaSやCloudflare Workers使った設計手札として役に立つ時が来るかもと
---
ReadModel
Edge上にキャッシュレイヤを置く
Cloudflare Workersのロケーションを最適化する
Service Bindings, Smart Placement, 0ms Cold Start
→物理的な距離によるネットワーク通信やnetwork waterfallのボトルネックを解消する
→グローバル展開が容易
フロントはRSCやWeb APIを介してキャッシュサーバーに問い合わせてリソースかき集める
スコープが十分小さければクエリはDB直読みでもいい
以下のような要件があれば、バックエンドは分離することを検討する
フロントエンドでのバックエンドとユースケースのインピーダンスミスマッチ
Policyや 集約(Aggregate)などのビジネスロジックが必要ならサービス(Service)やRepositoryへ逃す
この辺のWeb APIとしての役割はHonoやtRPCのキャッシュとバッチングみたいなミニマムな仕組みを使えるとシンプルにできる...かも?koushisa.icon #エアプ
WriteModel
ミューテーションのイベントとペイロードをEvent Sourcingする
Event Sourcingの副作用のキュー管理で、トランザクション制御とDBへの書き込みを分離する
詳細は後述
Event Sourcing
基本的な思想
ドメインイベントとEvent Sourcingは永続化の設計判断を遅らせることができる
ドメインイベント(Domain Event )に対してのN:Nの関連(relationship)とリアクティブ
この部分の設計進めるために、事前に要求分析をしておく
ロバストネス分析とかのUMLとか、マインドマップがあると嬉しい
ドメインイベントの洗い出し/ペイロード設計/境界づけられたコンテキスト
スケーラビリティ、転送量、集計要件などの非機能要件から多角的に考える
特に、集計はDB設計レベルで考慮しておかないと後からKPIが取れなくなるので注意
要求->要件満たせるならにデザインパターンからEvent Sourcing以外の方法選んでもいい
クラウド設計パターン - Azure Architecture
Enterprise Integration Patterns
構築技術
Cloudflareのエコシステムが進んでる印象koushisa.icon
Cloudflare D1のKey-value Store
Cloudflare Queuesで副作用のキュー管理
Cloudflare WorkersでStreamが使える
Cloudflare Pub/Subでメッセージングや差分管理
DynamoDBの事例もある
PayPayでのDynamoDB活用事例について
通知サービスに必要な要件
ただし「DynamoDBであるべき」という腹落ちは出来ていないkoushisa.icon #わかってないこと
日進月歩な世界ではあるのでこの辺は実際に触らないとみないとわからない気はする
ジャストインタイムで学ぶ
WriteModelからReadModelへの差分更新の反映 (Event Sourcingでの例)
クライアント
optimistic updateでブラウザ内のキャッシュとかステートを更新した上で、サーバー上の状態変化を監視する
useEffect
Recoil > atomEffects
Recoil > Recoil Sync
GraphQLのsubscription
Rx
データソースをsubscribeする仕組みがあれば、だけどあんまり使いたくはない
ObservableStreamは超かっこいいけど使い道の少ない技術
エラーやリトライ処理は発生する前提で考える
この辺の処理をクライアントに寄せすぎるとパフォーマンスやセキュリティ面での課題はある
サーバー
基本的に #エアプ だけど
Cloudflare D1をSSoT(唯一の情報源)としCloudflare QueuesでEvent Sourcingする
クライアントへのキャッシュ破棄通知については
メッセージング系は Stream API で、通知系はロングポーリング
通知系はほとんどの場合、ロングポーリングで事足りる
Cloudflare WorkersでStreamが使える
→Web Standard > ReadableStreamでokいいかなぁというイメージ
ブロードキャストとかチャネル制御とかが必要なら
Cloudflare Pub/SubやDurable Objects
フロントにデータ構造の知識を求めたくないので、基本的にはサーバー上で完結させたい
見た目の設計に引きずられてサーバの実装を毎回修正するのも嫌だし、サーバのデータ構造変化にフロントが巻き込まれるのも嫌
理想的にはApp Routerでキャッシュ境界をつくり、その中で差分検知して配下のコンポーネントを再マウント
AppRouter / RSCの差分更新をサーバーサイドで完結させたい
現段階では技術的に難しいっぽいけど出来たら嬉しいなkoushisa.icon
プレゼンテーション向けのストアをエッジに乗せつつクラサバの差分更新や同期を自動化したい妄想
この辺の仕組み統合したフレームワーク出てきたら試してみたい
言ってて思ったけど未来のVercelとかNext.jsがそれなのでは
VercelのEdgeの裏はCloudflareらしい
App Router > Server Actionsとかまさしく
URLの一意性などは考慮することあるかもしれない
ほか
段階的にマイクロフロントエンドへ移行していくための技術調査メモ