PocketBaseで開発する中でSQLiteの限界を感じ始めたが、まずデータベースを交換したわけではない。画面がコレクション名や生のレスポンスを知っていると、保存先の変更と同時に画面も広く修正する必要がある。将来PostgreSQLなどを選べるよう、先にこの依存を減らすことにした。
例えばゲーム一覧の編集では、値の保存に加えて権限確認、現在状態の更新、変更履歴が必要になる。画面から個別にコレクションを操作すると、一部だけ成功した場合の復旧が複雑になる。公開文書と非公開の下書きの閲覧条件も分散しやすい。
API v2では利用者の操作を要求の単位にする。画面が変更の意図を送り、サーバーが権限、保存順序、失敗時の処理を担う。保存構造への依存を減らすとともに、操作ごとの方針をまとめて確認できる構成である。
現在も認証と保存にはPocketBaseを使っている。店舗機能が対応する操作を文書化したcustom APIで提供し、画面には要求値、製品の応答、権限エラーと競合の意味を伝える。内部コレクションが変わってもこの使い方を保てれば、画面の修正範囲を抑えられる。
ブラウザーの操作はNext.js Route HandlerからDataKitサービスへ進み、サーバーレンダリングは同じサービスを直接呼ぶ。DataKitは認証済みのサーバーtransportとレスポンスの解釈を担当する。どちらも同じ製品型を使い、保存先の生データをそのままブラウザーへ流さない。
ゲーム編集では店舗ID、編集開始時の状態ID、追加・修正・削除する項目を送る。サーバーは編集権限と現在状態を調べる。先に別の人が保存していれば競合を返し、画面は入力内容を保持して最新の状態と比較できるようにする。
有効な要求は新しいゲーム状態、現在の参照、変更履歴、必要な報酬を一つのトランザクションで処理する。この仕組みによってまとめて保存するか、まとめて取り消せる。外部サービスへの問い合わせはその外で行い、応答を待つ間データベースのロックを保持し続けない。
Coreは再利用するスキーマとAPIの動作を持ち、Fullは既存データの運用移行、設定、ジョブ登録を追加する。新規環境を作る場合と、蓄積した履歴や参照を維持して変更する場合では検証条件が異なるためである。
現在のcustom APIはPocketBaseとSQLite上で動いている。PostgreSQLなどへの移行は今後の課題である。今回の変更により画面は操作全体の結果を受け取り、サーバーは権限と保存をまとめて検証できるようになった。新しい機能でも同じAPIを使うことが、この構成を維持する条件となる。
関連する記事と資料:店舗の変更履歴 · Musecatの開発記録