angular
redux

社内ツールのAngularプロジェクトに導入したRedux (ngrx/store)

More than 1 year has passed since last update.

【Angular、Vue.jsなど】マーケティング事業の開発現場でリアルに使われるJS事情
(2017年11月2日)
発表資料


名前: ちきさん (野口智弘)
所属: オプト
GitHub/Twitter/Qiita: @ovrmrw

We are hiring! :two_men_holding_hands::two_women_holding_hands:


Q. 社内ツール?

A. オプト社内で使われる依頼ツール

  • 社内の誰かが、別の誰かに何らかの作業を依頼する。
  • フォームの入力に応じてフォームが動的に変化する。(やばいやつ)
  • 一つの依頼は即日完了するわけではないので、数日に渡り進捗状況などを管理する必要がある。
  • 依頼に対してファイルを添付したり、依頼と別の依頼を関連付けたり、チェックリストが全てチェックされないと依頼を完了できないようにもできる。
  • 依頼毎にSlackのようなチャット板があって関係者がコミュニケーションを取れるようになっている。

Slackでやれば良いのでは...? :rolling_eyes:


そのへんのじじょうはまあいいとして、

  • 機能が込み入っている関係で、一つの依頼状況を画面に表示するために10個のHTTPリクエストが走っていてコレハ。。。と思った。
  • 例えば依頼No.100を表示した後、No.101を表示してからまたNo.100に戻ったとき、また10個のHTTPリクエストが走っていてヤハリ。。。と思った。
  • (なにかそうさするたびにすごいりょうのリクエストがおくられているぞ!)

いくら社内(人口700人くらい)でしか使われないツールとはいえ、割り当てられた貧弱なAPIサーバーの処理が重くて

開発部しょぼいとか思われるのは癪なので

なんとかしないといけないと思った。


そうだ、キャッシュすればいいんだ。 :star2:


HTTPリクエストの結果をキャッシュして、同じ結果になるリクエストを飛ばさないようにすれば、リクエストの数そのものを大幅に減らせるはずだ。 :zap:


(注: Webは基本的にステートレスな世界なのでキャッシュは安易に導入すると事故の元になります)


Angularでリクエストの結果をキャッシュしようと思ったら真っ先に候補に上がるのが、 ngrx/store というReduxをRxJSで再構築したライブラリ。(semi-official)

※ 主義主張には個人差があります ※


実際に出来上がったほぼキャッシュ目的のためだけのRedux

  • Action ... 530行
  • Reducer ... 370行
  • Effects(Middleware) ... 610行

一つの依頼状況を表示するために叩くAPI一覧

  • /api/requests/100 ... 依頼No.100の詳細データを取得できる。この中にタイムスタンプ(最終更新日時)が含まれている。
  • /api/requests/100/attachments ... 添付ファイル
  • /api/requests/100/checklists ... チェックリスト
  • /api/requests/100/destinations ... 関係者
  • /api/requests/100/inputs ... カスタム入力フォーム (こいつが地獄)
  • /api/requests/100/links ... 関連する依頼
  • /api/requests/100/media ... メディア媒体
  • /api/requests/100/media/accounts ... 媒体アカウント
  • /api/requests/100/results ... 進捗(チャット)

(今後さらに増えるのでは?)


依頼にいくつものデータが紐付いてはいるが、どれかが追加変更されるとタイムスタンプも更新されるため、

タイムスタンプが変わっていなければ前回取得したデータをキャッシュして返しても差し支えない

ということになる。


なのでこうなった。

  • /api/requests/100 ... タイムスタンプを持っているので毎回リクエストして最新データを取得する。
  • /api/requests/100/attachments ... リクエストする度に 依頼Noとタイムスタンプをキーにして ReduxのStoreにデータを格納する。View(表示画面)はStoreから流れてくるキャッシュを受け取って表示する。
  • /api/requests/100/checklists ...   〃
  • /api/requests/100/destinations ...   〃
  • /api/requests/100/inputs ...   〃
  • /api/requests/100/links ...   〃
  • /api/requests/100/media ...   〃
  • /api/requests/100/media/accounts ...   〃
  • /api/requests/100/results ...   〃

デモ
(大人の事情により外部への公開はできません)


ViewはStoreから流れてくるキャッシュを受けるだけ。自分から何かを取りに行くということはしない。(Observerパターン)

そして裏でこっそりキャッシュを更新している。


TaskDriverのStore発表資料用の図.png


TaskDriverのStore発表資料用の図 (1).png


TaskDriverのStore発表資料用の図 (2).png


リクエストの回数を大幅に減らし、事故らないキャッシュの仕組みを作ることができた。


社内でなんだか評判みたいで関わってた僕もうれしいです。 :tada:


Thanks :raised_hands_tone2: