サーバーサイドもDartで書いてきた。
ワンパターン化してきたのでフレームワーク化する。
とりあえず構想を発表する。
認証を楽にするため、HTTPサーバーはなくFirebaseサーバーとして振舞うものにする。
サポートする機能3つだ。
- Firebaseの型定義
- View
- コード生成支援
Firebaseの型定義
FIrebaseはJSONでデータをやりとりするため、エンコーダとデコーダが必要になる。
Firebase特有の機能があるので一般的なDartのJSONエンコーダーライブラリでは機能不足だ。サーバー側とクライアント側で微妙にユースケースが違うこともネックになる。
だから、型定義ファイルからサーバー・クライアントのコードを自動生成する。
定義ファイルの書式はDartにする。型定義ファイルのフォーマットとして、JSONは書きたくない。yamlも辛い。yamlは序盤は快調だが行が増えてくると辛くなる。
結局、型定義にどのフォーマットが適しているか。プログラム言語が一番いい。だからDartにした。これはそのDartを実行したりリフレクションで値を入れたりするものではない。DartのASTをとって解釈してそれを元にコードを生成する。Dartの書式で型を定義すれば読みやすいし各自のエディタのシンタックスハイライトや補完がきく。
将来はマイグレーション機能もつけたいと思っている。
Firebaseを使っているとDBのようにAlter Tableが打てないとめんどくさくなる局面がある。
型定義の変更履歴から既存のデータベースを変更できるコマンドを作れるはずだ。
2.view
FirebaseにDBのViewの機能が欲しい。もしかしたらこれは本家が対応するかもしれない。して欲しい。
例えばユーザーがいろんなグループに参加できるグループチャットアプリを作っているとする。ユーザーごとに取得したい書き込みはバラバラである。これを頑張ってクエリで表現するよりも
A チャットの書き込みを全部一箇所にまとめたデータ
B 誰がどのグループに所属しているかまとめたデータ
C ユーザーごとに所属するグループの書き込みをまとめたデータ
を別々に保持したい。
だから、AとBが変更された時にリアクティブにCを再作成したい。
どうするかというと、AとBの全データを引数にCの全データを作成する純粋関数を一個定義すると、A、Bが変更された時に毎回その関数が実行され、結果をFirebaseの所定の場所に書き込むものが欲しい。
いくつか最適化の方法を考えている。
DBにならってAとBをテーブル、Cをビューと呼ぶ。
第一に、テーブルの全データを毎回Firebaseから読みだすのは悪いので、テーブルのコピーをローカルファイルにおいておきたい。
第二に、作り直すたびにビューの全データをFirebaseに書き込むのは申し訳ないので、前回作成したビューをローカルに持っておき、差分をチェックしパッチを送る形にしたい。
第三に、どのテーブルが更新された時にどのビューを更新するのか、どのビューを更新するためにどのテーブルを読み出さないといけないのかを自動で判断する。ソースコードを解析することで可能だ。
第四に、実現方法がわからないので夢物語だが、ビューの1行がテーブルのどの行に依存しているかを判断できたら、毎回テーブルの全データを読み込まなくてよくなる。
コード生成支援
以前設計の逆流問題の話をした。
この最後の部分にinterfaceを自動生成していってくれればいいということを書いた。
それを含めたい。