backward compatibility とは? 既に動いているものを壊さない
backward compatibility とは、コンポーネントの新しいバージョンが、古いバージョン向けに作られたクライアント、データ、呼び出し側と今も動作することです。
backward compatibility は、段階的なロールアウトを可能にする静かな性質です。新しいバージョンが古い契約を今も守っていれば、古いクライアントが動き続けたままそれをデプロイでき、フラグデーも一斉の協調リリースも不要です。これを失うと、あらゆる変更がすべての consumer を同時に巻き込む同期的な大騒ぎになります。
実際に何を意味するか
新しいコードは、古い呼び出し側が送る入力を受け入れ、古い呼び出し側が理解できる出力を生成します。古いデータも今も読み込めます。古いクライアントが新しいバージョンと話しても破損に気づきません。互換性は、既に存在するものの視点から判断されます。
なぜ安全なデプロイを支えるのか
- rolling deploy の間、古いバージョンと新しいバージョンが同時に動く。
- サービスの独立したデプロイは、契約が互換のままである場合にのみ機能する。
- rollback を可能にする。古いバージョンが新しいデータを今も読める。
- 1つの変更のためにすべての consumer を協調させる必要をなくす。
構造上互換であること
安全な変更は、削除ではなく追加します。新しい任意フィールド、新しい endpoint、優雅に扱われる新しい enum 値。expand-then-contract パターン、新しい経路を追加し、呼び出し側を移行し、その後で初めて古いものを削除する、はすべての中間状態を互換に保ちます。
バージョン混在の期間
どんな rolling deploy でも、両方のバージョンが稼働する期間があります。backward と forward の compatibility が、その期間を安全にするものです。それらがなければ、誤ったバージョンに当たったリクエストが断続的かつ予測不能に失敗します。
CI での強制
パイプラインは API spec とデータベース schema を diff して breaking change を自動的に指摘でき、古いクライアントのテストを新しいバージョンに対して実行できます。これにより互換性は、レビュアーの判断ではなく build gate になります。
なぜ rollback がこれに依存するか
rollback は、以前のバージョンが新しいバージョンの書き込んだデータを今も扱える場合にのみ機能します。upgrade だけでなく rollback の経路もテストするパイプラインは、互換性が双方向で保たれることを確認します。
重要なポイント
- backward compatibility とは、新しいバージョンが既存のクライアントやデータと今も動作することである。
- rolling deploy、独立したデプロイ、安全な rollback の前提条件である。
- expand-then-contract の変更は、すべての中間状態を互換に保つ。