無限にTODOアプリを作っていき
今回はReact+TypeScript+Spring Bootで書いてみる。
フロントエンド構成
- TypeScript
- React
- Webpack
- Jest (一応入れたけど、習熟度が足りず画面のIFがガンガンぶっ壊れるから現状テスト書いてない)
- bulma (CSSフレームワーク, そういえばhack使ってみたかったけど忘れてた)
- ts-lint (お前もうちょい機能強くなって。エディタ拡張とかエディタ拡張とか)
フロントその他ライブラリ
サーバサイド構成
- Spring Boot
- thymeleaf3
- とりあえず感のあるh2
- こちらもとりあえずDBに初期データ突っ込むだけのflyway
- というか素振りみたいな感じでやってて何も固めずにガンガン作ってるのでマイグレーションもクソもない。
サーバーサイドその他
- gradle (wrapper)
- spotless (フォーマッタ)
- spring-boot-devtools (すごい。楽。)
ヤケクソで進めている感じが否めないのですが、色々悩んでSpringのコード書き散らして、散々紆余曲折した後に
色々コードぶち壊してなんとなくDBに保存するまでできたわけなんですが。
ごらんのありさまだよ!!
もともと何をしようとしてたかというと
IndexedDB(もしくはlocalstorage)をベースに
オフラインで動くようなタスク管理アプリケーションを弄っていた。
(というかこの構成で毎回TODOアプリ作ってる気がする。進歩がない。)
で、なぜそうしたいかというと結局オフラインでも動くと面白い、それだけなんですが
このデータの同期をどうするかで悩んでしまった。
サーバーの状態とクライアントの状態が常に存在している。
なので少し、頭の整理のためにメモを書こうと思う。
ここから下は本当にメモ
例えば、サーバーにつながらない状態でタスクを追加したとする。
これはサーバーとつながったら同期されてほしい。
つまり、クライアントで表示はされているけど
クライアントしかデータを保持していない状態がある。
保存されていないデータがあれば何回もサーバにリトライかけて保存しにいくのかというと
現実そういうわけにもいかない。とりあえず5回ぐらいで考えてみるとする。
そういった場合には保存されていない状態で画面ではクルクル回ってるアイコンを出したい。
リトライ5回して失敗したら、エラー表示みたいなのを出したい。
エラー表示のアイコンを押したらエラーメッセージを出しておきたい。
サーバーとつながらない状態でタスクを削除したとする。
まぁ当然サーバーとつながらないので論理的に削除できない。
しかし、画面上消したい。
グレーアウトしておくとする。
これもクルクルとエラーアイコン欲しい。
更新は削除して書けって感じでとりあえず無視しておく。
画面読み込み時ないしリフレッシュボタン押下にデータを更新したい。
ここが頭の中で整理ができていない。
まずここで存在する可能性があるのが次の状態のタスク。
- 画面で追加したけどサーバーに永続化されていないタスク
- 画面で削除したけどサーバーから削除されていないタスク
- 別のPCから追加したけどローカルストレージには反映されていないタスク
- 別のPCから削除したけどローカルストレージには反映されていないタスク
1はサーバーに追加したい。
2はサーバーから削除したい。
3はローカルストレージに反映して表示したい。
4はローカルストレージに反映して削除したい。
どうするのが正解なのかいまいち分からないので
とりあえず案を上げてみる。
上記4つの状態を観点として考える
タスクの状態に画面で生成された <–> 永続化されたみたいな状態を持つ
これはローカルストレージのみに保存する。DBには持たない。
すると、ローカルストレージから読みだした際に、永続化されていないことは分かる。
あとは永続化されていないものを登録しにいくだけである。
でも削除された時はどうなのか?これも状態を持つとうまくいきそう。
下みたいなイメージならどうか。
画面で保持 –> 永続化 –> 画面で削除 –> 物理削除タスクを4種類にわけて画面で保持しておく。
上で書いた状態のストレージを画面上で4種類用意しておいて、画面上は同じ場所に表示
画面で保持 –> 永続化 –> 画面で削除 –> 物理削除
楽にうまくいきそう。画面側で頑張ればいい。
観点3に関しては読み込み時にサーバーから取ってきたものを永続化されてるとして
データを持っておけばいい。観点1, 2は何も考えなくてもよさそう。
観点4の状態が難しい気がしたけど、永続化されている情報を持ってきた際に
永続化されている情報と突合すればいい。
またもう少し図とか書いて練ってみる。
リポジトリはここ
oauthで遊ぼうかと思ったけど余裕がなかった。
というか使う必要性が現状なかったのでディレクトリ名変えなきゃ・・・