下位互換性
下位互換性とは
下位互換性-システムが更新されたときに古いクライアント/消費者を受け入れて正しく処理するシステムのプロパティ。シンプル:サービス/イベントの新しいバージョンをリリースし、既存の統合は変更されません。
鍵:契約を破らないでください。すべての進化は、リメイクではなく、すでにリリースされたものを追加することによってです。
基本原則
1.Additive-First(
オプションで新しいフィールド/メソッド/イベントが追加されます。存在しないものは削除され、意味を変えません。
2.最低保証契約(MGC)
カーネルを定義する-スクリプトがその意味を失うことのないフィールド/操作のセット。コアは安定しています。それ以外はすべて拡張機能です。
3.寛容な読者
クライアントは未知のフィールドを無視し、新しい列挙(フォールバック)値を正しく処理します。
4.バージョンポリシー
変更を破る-主要な行('/v2'、'支払いを介してのみ。v2'、'イベント。v2')。マイナー-添加物。
5.観測可能性-契約の一部
クライアントのバージョン、フォーマット、機能フラグは、ログ/トラックおよびメトリックに表示されます。これにより、移行を管理できます。
セーフvs危険な変更
一般安全(BC-OK)
オプションのフィールド(JSON/Avro/Protobuf 'optional'/'nullable')を追加します。
新しいエンドポイント/メソッド/イベントを追加します。
追加の値を持つ列挙拡張(許容リーダー付き)。
検証の弱体化(最大化、代替フォーマットの追加)。
意味のないヘッダー/メタデータを追加します。
危険(破損)
フィールドの削除/名前変更、既存のフィールドのタイプまたは必須の変更。
ステータス/エラーコードのセマンティクスが変更されました。
他のフィールドにprotobufタグを再利用します。
イベントパーティションキーを変更します(集計の順序を壊します)。
SLA/タイムアウトをきつく締め、古い顧客を落下させ始めます。
インタラクションスタイル別
REST/HTTP+JSON
Additivity:新しいフィールド-'optional'、サーバーは古いクライアントからそれらを必要としません。
バージョン:メジャー-トランジット('/v2')またはメディアタイプ;マイナー-拡張機能と'を介して?include='/'?フィールド='。
エラー:均一なフォーマット;メジャーなしでコード/セマンティクスを変更しないでください。
ETag/If-Match:レースを行わない安全なアップデートのために。
Idempotency: 'Idempotency-Key' for POST-古い顧客はリトリートへの影響を'ダブル'しません。
gRPC/Protobuf
タグは変更されていません。削除されたタグは再利用できません。
新しいフィールド-'optional'/'repeated';デフォルト値は古いコードで正しく処理されます。
ストリーミング:マイナーなメッセージの順序/義務を変更しないでください。
エラー-安定したステータスのセット。new semantics→new method/service ('。v2')
イベント駆動(Kafka/NATS/Pulsar)+Avro/JSON/Proto
名前:'ドメイン。アクション。v {major}'。
Core vs Enriched: Core stable;enrichment-個々のタイプ/テーマ('。enriched')。
スキーマ互換モード:より頻繁にBACKWARD;CIは互換性のない変更をブロックします。
パーティショニング:キー(例:'payment_id')-契約の一部;それを変える-壊れる。
GraphQL
フィールド/タイプの追加-OK;delete/rename-'@deprecated'とマイグレーションウィンドウ。
メジャーなしで「nullable→non-nullable」を上げないでください。
複雑さ/深さを監視-制限変更=契約変更。
BCを維持するためのパターン
リバースピラミッドモデル:コアを安定させ、オプションで展開します。
機能ネゴシエーション:クライアントはサポートされている機能('X-Capabilities'/ハンドシェイク)をレポートし、サーバーは調整します。
デュアルラン/デュアルエミット:マイグレーション中は'v1'と'v2'を同時に保持します。
アダプター:プロキシ/ゲートウェイは「重い」クライアントに対する'v1↔v2'要求を翻訳します。
Expand-and-contract (DB用):最初に新しいものを追加し、書き込み/読み込みを開始し、古いものを削除します。
ガバナンスとプロセス
1.Contract Catalog (Schema Registry):互換性ポリシーを持つ単一の真実のソース。
2.CI/CDのLintersとdiffチェック:OpenAPI-diff、 Buf-breaking、 Avro/JSONスキーマ互換性チェック。
3.CDC/Consumer-Driven Contracts:プロバイダは、実際の消費者契約についてテストされています。
4.ゴールデンサンプル:回帰のための参照クエリ/応答/イベント。
5.変更管理:壊れることのRFC/ADR、日没の計画、コミュニケーション。
古いバージョンのDeprekateと削除
Mark obsolete('@deprecated'、説明、ヘッダー'Deprecation'、 'Sunset')。
移行ウィンドウ:事前に発表された日付、テストベンチ、コード例。
使用法のテレメトリー:他に誰が'v1'にあるか'?バージョンごとにメトリクス/ログをセグメント化します。
トラフィックをゼロにデュアルランしてから削除します。
観測可能性と運用基準
バージョン別のリクエスト/メッセージの割合。
リリース後の古いクライアントのエラー/タイムアウトの共有。
互換性のないペイロードの割合(ゲートウェイ/ストリームフィルタのスキームによる検証)。
消費者の移行の遅れ('v1'を聞く回数)。
下位互換性テスト
Schema-diff: remove/rename/type-changeに失敗しました。
契約テスト:古いSDK/クライアントは新しい実装に対して競争します。
E2Eカナリア:新しいバージョンへの古いトラフィックの一部、p95/p99の比較、コード、リトレイ。
イベントリプレイ:投影は、古いログからの新しいロジックによって、矛盾なく収集されます。
フォールトインジェクション:遅延/部分的な応答-古いクライアントは落ちません。
例
REST(添加剤)
それは:json
{ "id": "p1", "status": "authorized" }
それは次のようになりました:
json
{ "id": "p1", "status": "authorized", "risk_score": 0. 12 }
古いクライアントは'risk_score'を無視して作業を続けます。
Protobuf(タグ)
proto message Payment {
string id = 1;
string status = 2;
optional double risk_score = 3 ;//new field, safe
}
//Tags 1 and 2 cannot be changed/deleted without v2
イベント(コア+エンリッチメント)
支払いだよ。承認されました。v1'-カーネル(最小事実)。
支払いだよ。豊かになりました。v1'-部品;コア消費者は濃縮に依存していません。
アンチパターン
Swagger-wash:スキームが更新されましたが、サービスは古い方法(またはその逆)で動作します。
Hidden breaks:バージョンなしでフィールド/ステータスの意味を変更しました。
protobufタグの再利用:「静かな」データ破損。
ハードクライアント:慣れないフィールド/enumに落ちる。寛容な読者はいない。
メガエンドポイント:1つのオールインワン-すべての変更は潜在的なスクラップになります。
プレリリースのチェックリスト
- 変更は添加物です。核(MGC)は手つかずです。
- 渡されるLinters/diffチェック;壊れた旗はありません。
- クライアントSDKが更新されました(または添加拡張には必要ありません)。
- クライアントのための許容リーダーを有効にしました。enum-fallbackがチェックされました。
- メトリック/ログにはバージョンとケーパビリティフラグが含まれています。
- 潜在的な破損のためには、'/v2'、デュアルランと日没の計画があります。
- ドキュメント/例が更新されました、ゴールデンセットがあります。
よくあるご質問
後方対前方-違いは何ですか?
後方-新しいサーバーは古いクライアントで動作します。Forward-新しいクライアントは古いサーバーで正しく動作します(読み取りに耐性があり、デフォルトがきちんとしているため)。フルサークル-完全な互換性。
大きな変更のために常に'/v2'を行う必要がありますか?
はい、不変量/type/keys/semanticsが壊れている場合。そうでなければ、ラインを維持し、追加的に進化します。
enumはどうですか?
古いものの意味を変えることなく、新しい値を追加します。クライアントは、未知の値でフォールバックしている必要があります。
あなたがすでに「壊れている」場合はどうなりますか?
ロールバック、ホットフィックスアダプタ、デュアルラン、通信、移行ガイド付き「v2」リリース。
合計
下位互換性は進化の規律です。カーネルを安定させ、追加的に拡張し、寛容なリーダーを実装し、チェックを自動化し、意識的な非推奨を維持します。このようにして「、見えない」変化の瓦礫の下に顧客を残すことなく、迅速にプラットフォームを開発することができます。