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.4k
Domain Driven reDux - or Redux as CQRS
ピクシブ社内エンジニア勉強会(2018-12-07)の資料です
fsubal
December 08, 2018
Tweet
Share
More Decks by fsubal
See All by fsubal
負債になりにくいCSSをデザイナとつくるには?
fsubal
9
2.4k
Webデザインと フロントエンド技術🔰勉強会
fsubal
2
230
Tailwind CSSを本気でカスタマイズする方法
fsubal
17
7.1k
デザインシステムで Tailwind CSSとCSS in JSに分散投資をしたら良かった話
fsubal
19
6.4k
『Tailwind CSS実践入門』 出版記念基調講演
fsubal
8
5.1k
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
1k
SVG + React でつくる レイヤーの自由変形 / Layer Transformation with React + SVG
fsubal
1
9k
Other Decks in Programming
See All in Programming
Bedrock Agentsレスポンス解析によるAgentのOps
licux
3
840
チームリードになって変わったこと
isaka1022
0
200
Grafana Loki によるサーバログのコスト削減
mot_techtalk
1
130
Conform を推す - Advocating for Conform
mizoguchicoji
3
690
SwiftUI Viewの責務分離
elmetal
PRO
1
240
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
9
1.8k
『テスト書いた方が開発が早いじゃん』を解き明かす #phpcon_nagoya
o0h
PRO
2
220
Linux && Docker 研修/Linux && Docker training
forrep
24
4.5k
sappoRo.R #12 初心者セッション
kosugitti
0
250
Multi Step Form, Decentralized Autonomous Organization
pumpkiinbell
1
740
color-scheme: light dark; を完全に理解する
uhyo
3
310
DROBEの生成AI活用事例 with AWS
ippey
0
130
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
47
7.3k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
114
50k
RailsConf 2023
tenderlove
29
1k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Product Roadmaps are Hard
iamctodd
PRO
50
11k
Statistics for Hackers
jakevdp
797
220k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Site-Speed That Sticks
csswizardry
4
380
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.5k
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