Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Domain Driven reDux - or Redux as CQRS
Search
fsubal
December 08, 2018
Programming
1
1.3k
Domain Driven reDux - or Redux as CQRS
ピクシブ社内エンジニア勉強会(2018-12-07)の資料です
fsubal
December 08, 2018
Tweet
Share
More Decks by fsubal
See All by fsubal
Webデザインと フロントエンド技術🔰勉強会
fsubal
2
180
Tailwind CSSを本気でカスタマイズする方法
fsubal
17
6.8k
デザインシステムで Tailwind CSSとCSS in JSに分散投資をしたら良かった話
fsubal
19
6k
『Tailwind CSS実践入門』 出版記念基調講演
fsubal
8
4.9k
Sprockets CSSもやめる なぜ / Why stop using Sprockets for CSS too
fsubal
3
1.5k
The Majestic MPA
fsubal
8
3k
Backbone.Model に 型をつけて剥がす - Typing to destroy Backbone.Model
fsubal
1
970
SVG + React でつくる レイヤーの自由変形 / Layer Transformation with React + SVG
fsubal
1
8.7k
カリー化はナンの役に立つのか
fsubal
27
8.2k
Other Decks in Programming
See All in Programming
色々なIaCツールを実際に触って比較してみる
iriikeita
0
270
WEBエンジニア向けAI活用入門
sutetotanuki
0
300
VR HMDとしてのVision Pro+ゲーム開発について
yasei_no_otoko
0
100
役立つログに取り組もう
irof
26
8.7k
僕がつくった48個のWebサービス達
yusukebe
18
17k
推し活としてのrails new/oshikatsu_ha_iizo
sakahukamaki
3
1.7k
アジャイルを支えるテストアーキテクチャ設計/Test Architecting for Agile
goyoki
7
2.8k
offers_20241022_imakiire.pdf
imakurusu
2
360
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
1
290
Boost Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
850
Android 15 でアクションバー表示時にステータスバーが白くなってしまう問題
tonionagauzzi
0
140
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
360
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
72
5.3k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.8k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
246
1.3M
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5k
Thoughts on Productivity
jonyablonski
67
4.3k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
Unsuck your backbone
ammeep
668
57k
Designing Experiences People Love
moore
138
23k
Intergalactic Javascript Robots from Outer Space
tanoku
268
27k
Agile that works and the tools we love
rasmusluckow
327
21k
Side Projects
sachag
452
42k
Transcript
Domain Driven reDux あるいは Redux as CQRS pixiv Inc. f_subal
2018/12/07
2 誰 • pixivFACTORY フロントエンド • 巨大Reactコンポーネント建造業 • グッズ制作画面とか作ってます @f_subal
3
4 グッズの種類 グッズの仕様 テンプレート 材質 ページ レイヤー グッズの バリエーション アイテム
ドメインロジックが厚い フロントエンドを作っていく話 5
• Redux は ただのクライアントサイド CQRS だよ • C と Q
をドメインごとに切ると捗るよ ◦ けど純粋な ducks パターンはきついよ • ドメインモデルはプレーンな json と純粋関数で持つと良いよ • ある程度 Redux 習熟してる人向けです 6 話すこと
7
• みんな大好き状態管理層(強いグローバル変数) • 単方向データフローと相性がいい • フロントエンドでCQRSするやつ ◦ そのための pub /
sub と middleware の仕組みを提供するライブラリ ◦ https://speakerdeck.com/yamatatsu/reduxdebizinesurozitukuwogorigorishu-ku ?slide=12 8 Redux ってなんだっけ
9 http://krasimirtsonev.com/blog/articl e/my-take-on-redux-architecture
10 ThunkAction ( ≒ C 更新系) Selector ( ≒ Q
参照系) Action (ドメインイベント) http://krasimirtsonev.com/blog/articl e/my-take-on-redux-architecture
• CQRS とは ◦ Command(更新系)と Query(参照系)で実装を分離しようぜっていう考え ◦ 同じエンティティでも更新系と参照系では関心が異なるという前提に基づく • flux
は「データが単方向に流れる」という点から説明されることが多いが ◦ 実は Store の更新と参照を別のフローに分離したという点が結構重要 11 Redux as CQRS
Action 12
• flux における Action には2つの意味がある ◦ Domain Event を発行する ActionCreator
◦ UseCase としての Action( ex: redux-thunk, redux-saga, redux-observable ) • アプリケーション内で「起こった出来事」を表す ◦ ので、過去形で命名するようにしている • UseCase としての Action は、複数の Domain Event を投げることがある 13 Action = 更新系
• Action = アプリケーション内で「起こった出来事」 ◦ ので、過去形 or 完了形で命名するようにする ◦ 命令
とか 処理を表す名前にすると、実装者が責務を誤解する • ◎ → USER_PROFILE_LOADED // よい • △ → FETCH_USER_COMPLETE // まだマシ • × → FETCH_USER_BY_ID // やめて 14 Action = 起こった出来事
15
16
• 以下、暗に redux-thunk の使用を想定する • 「Ajax リクエストをして成功したら USER_LOADED を、失敗したら USER_LOADING_FAILED
を dispatch したい」みたいな、複数の action を発行しうる一連 の手続き • CQRS の C( Command )の部分 • Action との統一の都合上こちらも過去形で命名している 17 ThunkAction = ユースケース
18
• Redux 始めた人が最初に悩むやつ • Action と Reducer に何をどこまでやらせるか曖昧になりがち • ベストプラクティスとして
reducer には複雑な処理を書かない、と言われるが ◦ 言われるだけでなんでダメなのか分かってない人もいると思う ◦ 各種ドキュメントはあんまりこの辺教えてくれない 19 Action と reducer の責務問題
• case SET_NEW_ITEM: みたいな命名をしていると、あたかも reducer で副作用を起こし ていいかのような誤解が生じる ◦ SET_* 系の命名マジでやめたほうがいいと思う
• case NEW_ITEM_LOADED: と命名すれば、ロード自体はもう終わっていて、良いから後 は store に反映して、という理解になりやすい(たぶん) • 「アプリケーションで起こった出来事に反応して自身を更新」という構造にする 20 Action と reducer の混同は命名で矯正できる よ(過激派)
21
• 特定のドメインで起こりうる出来事の一覧を enum + ActionCreator として定義 ◦ 過去形で表現されるドメインイベントの一覧 • 複数の
Action を発行することのできるユースケースを Thunk Action として定義 ◦ 統一のため thunk も過去形で命名している ◦ ex) userProfileRequested() という thunk を投げると、USER_PROFILE_LOADED が dispatch される • reducer は Action の発生を見守る(何か起きたら自身を更新する) 22 factory における Action + Reducer
参照系 23
• 前提として Redux の Store はでかい • アプリケーションドメインが全部入った 1枚のJSON 24
Selector = 参照系
25 グッズの種類 グッズの仕様 テンプレート 材質 ページ レイヤー グッズの バリエーション アイテム
• コンポーネントがこのでっかい JSON から値を引く際、Store の内部構造を知らなくても すっと引ける仕組みが欲しい • これが selector(実装には自動メモ化機能などがついた reselect
が使われる) • CQRS の Q の部分(参照系のビジネスロジック) 26 Selector = 参照系
27
ドメインごとに切る 28
• action, reducer, selector をどういう構成で置くかはプロジェクトごとに結構違う • 一番良く見るのは次の形式 /actions user.ts /reducers
user.ts /selectors 29 redux のディレクトリ構成
• ファイル移動が多くなりがち • 「俺は user が規約に同意したことを true にしたいだけなのに、なんでディレクトリ 4つもま たいでるの、アホなの」問題
• 対抗策としていわゆる ducks パターンという設計が出てきた 30 /actions 形式の問題
• 同じドメインの action, reducer, selector を1ファイルにまとめる設計 • 各 ducks は完全に中に閉じる(基本相互に関係しあわない)
/modules /user duck.ts /item duck.ts 31 ducks パターン
32 https://webbibouroku.com/Blog/Article/redux-ducks
• ducks パターンだと流石に閉じすぎててつらいということから出てきた(多分) • ドメインごとに切る点は踏襲してるが、ファイルは別々 /domains /user action.ts reducer.ts selector.ts
33 re-ducks パターン
• だいたい re-ducks パターンの変形 • 各ドメインは相互に干渉し会える ◦ 「Product の thunk
が Specification の actionを発行」とかを許容している ◦ 純粋な ducks パターンで 1 ファイルにまとめる と ↑ がやりずらくなるのでやめた 34 factory のファイル構成
• 実はリニューアル前の旧エディタは /actions のようにディレクトリを切っていた • 結局の所 Store 内の 1個の値を更新するのにファイル移動が異常に多くて萎えた •
新しい設計でもファイル移動は発生するが、同じドメインなら同じフォルダなので面倒さは 少ない • ドメインごとにフォルダを切ったことでコンテキストが境界づけられたのも良かった • 結論おすすめです 35 factory のファイル構成
ところで 36
• 型定義 + 関数 + 定数 の集まり • みんなよく types.ts
とか userUtil.ts とか constants.ts とか作るけど、あれを1ファイルに纏 めたもの • action と selector、あるいはコンポーネントからも 呼べる共通関数とかおける • 別の機会にこれだけで話したい …かも 37 model.ts って何や
38
まとめ 39
• Redux は ただのクライアントサイド CQRS だよ • C と Q
をドメインごとに切ると捗るよ(けど純粋な ducks パターンはきついよ ) • ドメインモデルを純粋な形で持つようにすると良いよ 40 まとめ
Redux as CQRS あるいはドメイン駆動 Redux pixiv Inc. f_subal 2018/12/07