Vuex ORM についてなにか書いてみようとしたがやめた話

※ Retty Advent Calendar 2018 14日目の記事です。
昨日 13日目は @ryota-yamamoto　[「SEO に強くなる構造化データマークアップ ~ Nuxt.js で JSON-LD をコンポーネント指向で管理する ~」](https://qiita.com/ryota-yamamoto/items/2c43c606d9a96fc4de5f) でした。 管理が複雑かマンパワーかの二極になりやすいJSONldを楽に管理できるようになるのは最高ですね。

フロントエンド担当しております高瀬です。
今年5月にRettyにJoinさせていただいたのですが、もう年も変わるということで
時間の流れがはやく驚きを隠せないでいます。
ここ最近 [Vuex ORM](https://github.com/vuex-orm/vuex-orm) を個人的に調べており、それについて何か書くことができればと思っていたのですが、
書かなくてもいいなと考えあらため、その結論に至った経緯を記載できればと思います。

-----

# まずはじめに

弊社では現在フロントエンドフレームワークに [Vue.js](https://vuejs.org/) を採用しております。
また、状態管理には [Vuex](https://vuex.vuejs.org/) を利用しております。

#  Vuex ORM に興味をもった話

※ 以下は例えのため Retty 内にあるコンテンツや機能などとは関係ありません。

よくある口コミ機能を例にすると
誰がどこの何に口コミ投稿したかの情報は

口コミの対象となる商品や店舗さん（以後商品に統一）のデータ
誰が投稿したかわかるユーザーデータ
何を投稿したのかの口コミ内容

この3点が最小限必要となります。

それぞれのデータごと、またそれぞれを紐づけるリレーションテーブルが DB にあることが想定され
（中には JSON がそのまま格納されているなど、知ってはいけないケースも想定されますが...）
フロントから API を叩いた場合、大抵の場合サーバー側でそれらの関連を解決し返してくれる、
若しくは、商品情報を取得し終えたら商品の ID をパラメータに含め API を叩くことが想定されます。

このケースの場合、口コミは商品の中に入っているケース、口コミのみのデータで持っているケースなどが想定されますが、
すくなくともユーザー情報はサービスに登録されている不特定数のユーザー一覧を取得することは無理があるので、
口コミ情報にユーザー情報が入っていることでしょう。

また、ユーザーが他ユーザーをミュートできる機能があったとしましょう。
気になった時だけクリックなどをしてもらい内容が確認できるが、基本的には表示させない UI だと仮定してください。
すると、イメージ的には 口コミ ＞ ユーザー ＞ ミュートフラグ と情報が入っていそうですね。

口コミ以外でも、例えばお気に入りしているユーザー一覧機能があったとして、そこでもミュートユーザーは表示させたくないなど-----

するとミュートを設定した時点でそれぞれのコンテンツに反映されなければいけないため、
ユーザー情報はユーザー情報として、なにかのコンテンツに属したものではなく単独の Model として見たいケースが発生します。

そこでこう思うのです。
**フロント側でもリレーショナルマッピングあった方が良くない？**

Vuex を利用しての ORM プラグイン  [Vuex ORM](https://github.com/vuex-orm/vuex-orm) これこそ求めていたものなのではないか？
フロントエンドで様々な複雑なデータを扱うのであれば...-----

# Vuex ORMでなくていいかもと思い始めた話

Rettyではコンポーネント指向により中で閉じるように設計されているため
元よりVuex ORMが欲しいという場面には遭遇しにくいのですが、
どうにもデータの種類やDB自体は多いために、フロントエンド側でも複雑にネストされた情報を扱う必要が出てくるのではないかとどうしても不安に感じていました。 

遅かれ早かれフロント側で Vuex ORM と似たようなことは行うであろう...

そんな中、弊社ではマイクロサービス化をひとつのマイルストーンとしました。
絶賛プロジェクト進行中となっております。

マイクロサービス化に伴いフロントエンドはどう変化していくでしょうか？
遅かれ少なかれマイクロサービス化を行うプロジェクトでは
フロントエンドも [マイクロフロントエンド](https://micro-frontends.org/)（[日本語](https://micro-frontends-japanese.org/)）化していくことが想定されます。

[マイクロフロントエンド](https://micro-frontends.org/)としてフロントエンドが WebComponents のように独立して動く場合
DOM is API としてデータをやりとりするのであれば、必要なデータはそれぞれ整理されてUIに渡るため
ORM されている恩恵がコンテナ層くらいでしかないのです。

すると [Vuex ORM](https://github.com/vuex-orm/vuex-orm) で解決できる層が限定されてしまい、
思ったよりも恩恵がないことにコストをかけすぎてしまう心配が発生します。

## 結局何が意識をかえたのか

コンポーネント指向という設計指針やWebComponentsという技術があり、なぜマイクロフロントエンドにより意識が変わったのか。
これは技術スタックがComponents（あるいはチーム）間で技術に依存しないインターフェースを提供する方針だからです。
既存の1プロジェクトとして運用する場合、技術は統一されるべき、
そして無意識のうちにVuexがアプリケーション全体から参照できるべきものとして考えてしまいがちでした。
[マイクロフロントエンド](https://micro-frontends.org/) から見るにVuexを使うにしても Productチームのみとなり、それぞれのチームはそれを知らず、インターフェースにのみ注目していれば良いということですね。

# 結局ケースバイケース

しかしながら、BFF を通せるケースばかりでもなければ、規模によってマイクロサービス、[マイクロフロントエンド](https://micro-frontends.org/)で
運用するにはコストパフォーマンスが合わない。しかし、内容は結構複雑なリレーションを行なっているケースなどはあります。
そういったケースでフロントエンドで頑張るために [Vuex ORM](https://github.com/vuex-orm/vuex-orm) は選択肢として残ると思います。
もちろん、そうでなくても機能過多なケースもあるでしょう。

# さいごに

そもそも、 [Vuex ORM](https://github.com/vuex-orm/vuex-orm)  に興味を持ったのは個人ツールを開発しようとしていたことがきっかけでした。
そのツールはフロントエンドにマスタとして様々なリレーションされたデータを持ち、
それらをフィルターすることを目的としていたため、目的が合致していました。

しかし、今回 Retty Advent Calendar ということで改めて社内の技術方針と比較してみると
決してベストばかりじゃないなぁと思い、その経緯を整理し現在に至りました。