実践Firestore を読んだ

Firestoreって人気あるよなー。という印象があったので過去に触っていたFirebase Realtime DatabaseやCloud Datastoreとはどう違うんだろう?
また、 Dynamodbとの違いなんかもわかるとイイな。で本を開いてみた。

Firestoreの正体

のっけから核心に迫ってくれる。
「クライアントアプリから読み書きが可能なデータベース」といったところだった。
Realtime Databaseがここに取り組んだが、弱点であったデータモデルやクエリを改善したらしい。
データベースのよくある分類としては「ドキュメント指向NoSQL」だ。

Firestoreを利用する上での大まかなポイントは
* 「セキュリティルールを使いこなしてバリデーション」
* 「クライアントサイドでどうしても整合性を取るのが難しければCloud Functions」
* 「Cloud Functionsはバックグラウンド実行可能ならバックグラウンドを積極的に使う」
* 「読み取りオペレーションの回数を抑制するためにリアルタイムリスナーを活用する」

クライアントSDKの出来が非常に良くてオフラインでの動作もよしなにしてくれる。
ただ、デフォルトでオフライン動作のためのキャッシュが有効になっているプラットフォームもあるのでそれを知っていないと混乱することもあろうとのこと。
クライアントSDKの利用時はまず、オフラインでの挙動を確認しよう。

アトミックオペレーション

サーバサイドでデータベースを嗜んでいると気になるのがトランザクションだ。
Firestoreではアトミックオペレーションという機能群のなかの1つにトランザクションがある。
アトミックオペレーションには「トランザクション」に加え、「一括書き込み」、「FieldValue」というのもある。

トランザクション

本には明確には書いていないが、クライアントサイドとサーバーサイドで排他制御の仕様が違う。

クライアントでは本にあるような仕様だが、サーバーサイドでは上記のドキュメントにある仕様になっているので要チェックだ。

クライアントとサーバどちらからFirestoreに書き込むのかで仕様が変わるのは、クライアントからの直接書き込みを許容しているが故の特徴だなと感じた。
トランザクションが必要なケースで、クライアントで実行しようと思っていたが悲観ロックが欲しくなったらそれはサーバで実行しようね。という導きにも思える。
トランザクションが必要!となったら排他制御の仕様がマッチする側実行環境を選ぼう。というものと捉えるといいのだろう。

一括書き込み

最大500件のset/update/deleteといったオペレーションを実行できる。
お値段としては個別オペレーションごとに使用料を計上するので一括だからお得!とかはない。

本では「バックエンドで大量のデータセットを書き込むときにも利用します。」的な記述はあるが、下の公式ドキュメントの「注」を読むと「データ一括入力するには、並列書き込みのほうが有利」的なことが書いてある。
サーバでの一括入力の実行は、Collectionに対する書き込みの上限パフォーマンスに触れないようにgroutineでもなんでも並列化して個別に入力したほうがいいことがわかった。
ぐぐると検証してくれている人がいて非常にありがたい件だった。

一括書き込みは書き込みの単位でアトミックにはなるので、書き込みの特徴に応じて「一括書き込み」or 「並列個別書き込み」が選択できるといいのだろう。

FieldValue

ドキュメントの数値フィールドのインクリメントや、サーバ(firestore上の)タイムスタンプ、Arrayの操作などが提供されている。
トランザクションを使わずとも済む操作がこちらで用意されている場合、FieldValueを利用した方がいいらしい。

オフラインモード

クライアントSDKには良くできたオフラインモードがある。
自分的に気をつけよー。と思ったのは書き込み時の挙動だ。自分的にはオフライン時には書き込みは失敗して欲しいものだと思ったが、SDKは非同期タスクを作成しオンラインになったときに実行するという。
本にもあるが「原則として書き込みオペレーションは将来何かの時点で成功するものとみなしてよく、その前提のもとでアプリケーションを設計します。」という感じだ。

オフラインモードはSDKの設定から無効にしたりキャッシュのサイズを変更できるもののreadは有効、writeは無効といった制御はできなそうだ。(ちゃんと調べてないよ!)
writeはトランザクションを利用する場合オンラインである必要があるため、どーーしてもオンライン時のみ書き込みたい場合にはトランザクションが「本来の用途で不要でも利用する」という手段がとれるのだろうか?

セキュリティルール

ホワイトリスト形式で記述していくルール、CRUDそれぞれ宣言できてREADはget/listでまた分けることができるので分けること推奨とのことだ。

セキュリティルールを定義することでFirestoreはサーバサイドのアプリケーションなしで安全なデータベースの実装!を実現しているがこのセキュリティルールはなかなか曲者だろうと印象を受けた。
JavaScript…ぽい構文でバリエーションロジックを書くわけだが、自分は受け入れるのが時間がかかりそうだ。
ドキュメントのスキーマチェックのようなロジックを書くのはとくにだ。そう思ったので「protobufからロジック生成できたりしないのかな?」と探してみたらあった。

データモデリング

重要どころは
* ドキュメントは加工なしでクライアントサイドが利用できるようにする。
* ドキュメントで機密レベルが一意に決まるようにする。
* マップ型、リスト型のフィールドはサブコレクションを優先して利用する。
* ネストした要素はサブコレクションで代替可能か検討する。
といったところに読めた。

また、Firestoreでもイミュータブルデータモデルの話が出てきた。この話がでてくるとその後CQRSが出てくる。
CDCの機能が提供されているとイミュータブルデータで書き込み、CDC経由で読み込み用にクライアント都合に合わせたクエリ用データを書き込み。ってのは自分の好きなパターンだ。
CDCがあれば大体実現はできるが、Firestoreはクエリ用データへのアクセスがサーバサイド実装なしで実現できるので非常に大きいメリットだ。
さらにリアルタイムリスナーがあることでバックグラウンドで更新されたクエリ用データの変更に合わせてクライアントサイドがリアクティブに表示項目を変えることが容易に実現できる。

一通り読んでみて

ザーッとFirestoreの特徴を掴めた気がするので非常に良かった。集中したら2日で読める量だったのもGood。
気になって公式ドキュメントを見てみると新たな視点を獲得なんてのもあるので本を読んで気になったところは積極的に公式ドキュメントを読むべきだと思う。要は本だけで本番利用に踏み切れるぞイッタレー!とするのは勇気がいる。

本を読んだし、Firestoreは非常に面白そうなツールだとわかったので早速触ってみたいが、自分はお財布に厳しいので業務で触るようになってから… と思った。
しかし、FirestoreにはEmulatorがありタダで雰囲気を掴めることがわかったのでボチボチやっていくぞ!


この記事が気に入ったらサポートをしてみませんか?