スキーマベース開発でインフラ間のバージョン差によるバグを抑制するアイディア

悩み事。
互換性を保つ開発の複雑さ。
手元のPCであれば、フロントもバックもDBも同時に更新ができるので気づきにくいが、それぞれのインフラは残念ながら一気にリリースができないため、壊れないようにするためにもリリース順序が大事。
ある項目をDBから削除するとき。
- フロントエンドのその項目に関する依存を消す
- バックエンドのその項目に関する依存を消す
- DBのその項目を消す
ある項目をDBに追加するとき。
- DBにその項目を追加する
- バックエンドにその項目を追加する
- フロントエンドにその項目を追加する
ある判別ロジックをフロントエンドから渡してほしいとき
- フロントエンドに判別ロジックを実装しAPIに渡す
- バックエンドに判別ロジックを受け取り判別する実装をする
もしくは
- バックエンドに判別ロジックをnullableにしてフロントから渡してもらう実装を書く
- フロントエンドに判別ロジックを実装する
- nullableを削除する

ビッグバンリリースとかで追加と削除を同時にやったら地獄。
一般的に削除はフロントエンドから、追加はDBからやる。ここでジレンマが生じる。
そこで、改善策としては、追加コードをnullableにしつつ、フロントからリリースし、最後にnullableを消す。

ここらへんをうまく楽に管理してくれるツールはないのか。

一般的な解決策としては、
セマンティックバージョニングを採用し、基本的に値の削除はしない。
削除する項目はdeprecatedにしておき、メジャーバージョンアップ時にフロント側から徐々に消していく。それで互換性を保持する。

基本的にインフラをともにする奴ら同士は、一気にリリースすることができるから、究極1つのサーバーにフロントもバックエンドもDBもいれれば、こんな問題は起きないんだけど。

スマホアプリケーションとか最悪だよね。
アプリのバージョンアップはユーザーに依存しているから。ユーザーが古いバージョンを使っている限り、常に古い互換性のことを考えておかないといけない。

各インフラ単位ごとに、スキーマとスキーマバージョンをもたせるのはどうだろうか?
スキーマ自体は統一して扱えるようにJSONとかで表現する。
DBはDBスキーマを提供する
バックエンドは DBスキーマに依存しAPIスキーマを提供する
フロントはAPIスキーマに依存する
スキーマの項目を追加時はマイナーバージョンアップ
スキーマの項目を削除時はメジャーバージョンアップ
それ以外のリリース時はパッチバージョンアップ
それを統一した方法で扱うことができれば

各インフラの起動時に自分のもっているスキーマのバージョンと依存サービスの現行バージョンを確認する。マイナーバージョンやパッチバージョンが異なっていてもよい。メジャーバージョンが異なっていれば....
いや、これだと、DBをメジャーバージョンアップでリリースしたあとに、バックエンドがうまくリリースできないな。。
いっそのこと、バージョンいらないんじゃない?スキーマの差分だけ比較する

ほかによくある対応としては、インフラのすべてのバージョンを一致させること
フロント v1.2.1
バック v1.2.1
DB v1.2.1
みたいな

インフラというかリリース単位といったほうがいいか

メジャーバージョンアップデート時には、旧メジャーバージョンのリリース単位を物理的に残して、並行運用するのもありかもしれない。DBとかはムリだけど

ここらへん、ビッグテックはどう解決してるんだ?

メジャーバージョンのx.0.0では既存のdeprecatedを削除する警告の意味をもたせてもいいかもしれない。
x.1.0以上で実際に削除を行っても良い。

フロント側は依存先のスキーマと自信が保持しているスキーマのメジャーバージョンが異なれば、強制的にアップデートされるような仕組みをもたせておく。
そしてフロント側のメジャーバージョンアップデートでは、deprecate依存を強制排除しないといけない。