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.6k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Domain Driven reDux - or Redux as CQRS
ピクシブ社内エンジニア勉強会(2018-12-07)の資料です
fsubal
December 08, 2018
More Decks by fsubal
See All by fsubal
負債になりにくいCSSをデザイナとつくるには?
fsubal
11
3.6k
Webデザインと フロントエンド技術🔰勉強会
fsubal
2
360
Tailwind CSSを本気でカスタマイズする方法
fsubal
17
8k
デザインシステムで Tailwind CSSとCSS in JSに分散投資をしたら良かった話
fsubal
20
7.6k
『Tailwind CSS実践入門』 出版記念基調講演
fsubal
9
5.5k
Sprockets CSSもやめる なぜ / Why stop using Sprockets for CSS too
fsubal
3
1.7k
The Majestic MPA
fsubal
8
3.4k
Backbone.Model に 型をつけて剥がす - Typing to destroy Backbone.Model
fsubal
1
1.2k
SVG + React でつくる レイヤーの自由変形 / Layer Transformation with React + SVG
fsubal
1
10k
Other Decks in Programming
See All in Programming
Android CLI
fornewid
0
210
これって Effect でできたのでは? / TSKaigi Mashup Kansai #2
susisu
0
150
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
1.7k
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
450
数百円から始めるRuby電子工作
tarosay
0
140
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
180
VibeCodingからAgenticWorkflowへ
starfish719
0
330
FDEが実現するAI駆動経営の現在地
gonta
2
270
Lean は証明の正しさを確認するためだけのツールって思ってませんか?
inoueasei
1
150
メールのエイリアス機能を履き違えない
isshinfunada
0
230
作るコストが小さくなった時代 幸せに働くために改めて考えたいこと 〜エンジニアとして価値を出し続けるために注視している二分野〜
yuppeeng
0
190
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
600
Featured
See All Featured
Prompt Engineering for Job Search
mfonobong
0
400
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
350
Building Adaptive Systems
keathley
44
3.2k
Building AI with AI
inesmontani
PRO
1
1.1k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
KATA
mclloyd
PRO
35
15k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
460
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Building Applications with DynamoDB
mza
96
7.2k
Balancing Empowerment & Direction
lara
6
1.2k
How to train your dragon (web standard)
notwaldorf
97
6.7k
Optimising Largest Contentful Paint
csswizardry
37
3.9k
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