スキーマレジストリとデータの進化
スキーマレジストリが必要な理由
スキーマレジストリは、データ契約(API、イベント、スレッド、メッセージ、ストア)のための一元化された真実のソースです:- 予測可能な進化:互換性ルールと自動破損チェック。
- 繰り返し可能性と透明性:バージョンの履歴、who/when/why changed。
- 標準化:ユニフォーム名、エラーフォーマット、トレースフィールド、PIIラベル。
- CI/CDとの統合:生産の前に変更を壊すことを妨げること。
レジストリはProtocol-firstとcontractの互換性をリンクしており、変更を迅速かつ安全に行うことができます。
フォーマットとアプリケーション
JSONスキーマ:REST/HTTPペイロード、ドキュメント、構成。
Avro:イベントバス(Kafka/Pulsar)、 フィールドIDによるコンパクト/進化。
Protobuf: gRPC/RPCの二進法の有効な、厳密な札。
GraphQL SDL:型とディレクティブのスキーマ、'@deprecated'による進化。
SQL DDLをアーティファクトとして:合意したビュー(外部ストアフロントなど)を慎重に修正します。
互換性モード
BACKWARD:新しいスキーマは古いデータ/メッセージを読み込みます。ペイロードを添加的に拡張する生産者に適しています。
FORWARD:古い消費者は新しいデータを正しく読み取ります(寛容な読者が必要です)。
FULL:両方を組み合わせます(より厳密で、公共の契約に便利です)。
NONE:チェックなし-サンドボックスのみ。
- イベント:より頻繁にBACKWARD(プロデューサーはオプションでペイロードを拡張します)。
- パブリックAPI:クライアントのFULLまたはBACKWARD+厳格な許容リーダー。
- 内部プロトタイプ:一時的にNONEですが、トランクにはありません。
安全(添加物)と危険な変更
添加物(OK):- オプションのフィールド/タイプを追加します。
- 新しい値を持つEnumエクステンション(許容リーダー付き)。
- 代替プロジェクション/イベント('。enriched')を追加します。
- 制約を緩和する('minLength'、 'maximum')。
- フィールドの削除/名前変更またはタイプの変更/必須。
- スレッド内のstatuses/codecs/orderのセマンティクスを変更します。
- protobufタグの再利用。
- イベントのパーティションキーを変更します。
組織を登録する
ネーミングとアドレス指定
グループ/スペース:'payments'、 'kyc'、 'audit'。
名前:'支払い。承認されました。v1'(イベント)、'支払い。v1。CaptureRequest '(gRPC)、' orders。v1。Order '(JSONスキーマ)。
名前のメジャー、メタデータ/スキーマバージョンの未成年者。
メタデータ
'owner'(コマンド)、'domain'、 'slas' (SLO/SLA)、 'security。tier '(PII/PCI)、' retention'、'compatibility_mode'、'sunset'、'changelog'。
ライフサイクル管理
Draft→Review→Approved→Release→Deprecated→Sunset。
自動バリデータ/リンタ、手動デザインレビュー(APIギルド)、リリースノート。
CI/CDへの統合
1.プリコミット:ローカルリンタ(Spectral/Buf/Avroツール)。
2.PRパイプライン:schema-diff→compatibility mode check;壊れることを妨げること。
3.Artifact publish:一貫したスキーマをレジストリにプッシュ+SDK/モデルを生成します。
4.ランタイムガード(オプション):ゲートウェイ/プロデューサーは、現在のスキームに対してペイロードを検証します。
- 'openapi-diff --fail-on-breaking'
- 'buf breaking --against
' - 'avro-compat --mode BACKWARD'
- 金色のサンプルを生成し、CDCテストを実行します。
スキームの進化: プラクティス
Additive-first: 'optional/nullable' (JSON)、 'optional' (proto3)、 default#Avro。
リバースピラミッドモデル:コアは安定しており、濃縮は近くにあり、オプションです。
Dual-emit/dual-write for major: 'v1'と'v2'を並列に発行します。
サンセットプラン:日付、用途、警告、アダプター。
寛容なリーダー:クライアントは未知のフィールドを無視し、新しい列挙を正しく処理します。
スキームとチェックの例
JSONスキーマ(フラグメント、添加フィールド)
json
{
"$id": "orders.v1.Order",
"type": "object",
"required": ["id", "status"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"status": { "type": "string", "enum": ["created", "paid", "shipped"] },
"risk_score": { "type": "number", "minimum": 0, "maximum": 1 }
},
"additionalProperties": true
}
Avro(互換性のデフォルト)
json
{
"type": "record",
"name": "PaymentAuthorized",
"namespace": "payment.v1",
"fields": [
{ "name": "payment_id", "type": "string" },
{ "name": "amount", "type": "long" },
{ "name": "currency", "type": "string" },
{ "name": "risk_score", "type": ["null", "double"], "default": null }
]
}
Protobuf(タグを再利用しない)
proto syntax = "proto3";
package payments.v1;
message CaptureRequest {
string payment_id = 1;
int64 amount = 2;
string currency = 3;
optional double risk_score = 4; // additive
}
// tag=4 зарезервирован под risk_score, его нельзя менять/удалять без v2
イベントレジスタとパーティショニング
イベント名:'domain。アクション。v {major}'('支払い。捕獲された。v1')。
パーティションキーは契約('payment_id'、 'user_id')の一部です。
Core vs Enriched: '。v1' (core)および'。enriched。v1'(詳細)
レジストリの互換性:テーマ/タイプレベルのモード。CIは互換性のない変更を拒否します。
移行管理
展開→マイグレート→コントラクト(REST/gRPC):1.フィールド/テーブルを追加2)新しいフィールドの書き込み/読み込みを開始します。3)日没後に古いものを削除します。
- デュアルエミット(イベント):'v1'/'v2'と平行になり、コンシューマー/プロジェクションの移行、そして'v1'の削除。
- リプレイ:ログから新しいダイアグラムへのプロジェクションの再構成(互換性とマイグレータのみ)。
- アダプター:複雑なクライアントの'v1↔v2'を翻訳するゲートウェイ/プロキシ。
安全性とコンプライアンス
図のPII/PCIラベル:'x-pii: true'、 'x-sensitivity: high'。
アクセスポリシー:誰がスキーム(RBAC)を公開/変更できますか?
暗号:スキーマバージョンの署名、不変監査ログ(WORM)。
忘れられる権利:暗号化/暗号消去を必要とするフィールドを指定します。レジストリのガイダンス。
オブザビリティと監査
ダッシュボード:変更の数、タイプ(マイナー/メジャー)、拒否されたPRの共有、バージョンの使用。
監査証跡:スキームを変更した人、PR/ADRへのリンク、関連するリリース。
ランタイムメトリック:検証に失敗したメッセージの割合;互換性インシデント。
ツール(サンプルスタック)
OpenAPI/JSONスキーマ:Spectral、 OpenAPI Diff、 Schemathesis。
Protobuf/gRPC: Buf、 buf-breaking、 linters。
Avro/Events: Confluent/Redpandaスキーマレジストリ、Avro-tools、 Karapace。
GraphQL: GraphQL Inspector、 GraphQL Codegen。
レジスタ/カタログ:Artifact Registry、 Gitベースのレジストリ、バックステージカタログ、カスタムUI。
ドキュメント:Redocly/Stoplight、 Swagger-UI、 GraphiQL。
アンチパターン
Swagger-wash:このスキームはサービスの現実(またはその逆)を反映していません。
無効な互換性チェック:「緊急」→製品が壊れます。
protobufタグの再利用:サイレントデータの破損。
単一の互換モード「すべてのために」:異なるドメインは異なるモードを必要とします。
パブリックスキームとしてのRaw CDC: DBモデルの漏洩、進化の不可能。
実装チェックリスト
- ドメイン別にアーティファクト形式と互換性モードを定義。
- Linterとschema-diffはCIで設定され、PRは破損時にブロックされます。
- クライアントの寛容な読者のために有効になりました;'additionalProperties=true'(該当する場合)。
- 主な変更は、RFC/ADRを通過します、サンセットプランとデュアルエミット/デュアルライトがあります。
- 回路はPII/PCIとアクセスレベルでマークされています。監査が有効になっています。
- バージョンの使用と互換性の障害ダッシュボード。
- レジストリからSDK/モデルを生成することはパイプラインの一部です。
- ドキュメントとゴールデンサンプルが自動的に更新されます。
FAQ(よくある質問)
レジストリなしでスキームをGitに保存することは可能ですか?
はい、しかし、レジストリは互換性API、検索、メタデータ、集中ポリシー、およびオンザフライ検証を追加します。最良のオプションは、上のストレージ+UI/ポリシーとしてのGitです。
互換モードを選択するにはどうすればよいですか?
変更の方向を見てください:プロデューサーがペイロードを拡大する場合-BACKWARD。パブリックAPI/SDKの場合-FULL。高速プロトタイプの場合-一時的にNONE(トランクにはありません)。
必要な場合はどうすればいいですか?
v2の準備:デュアルエミット/デュアルラン、日没日付、アダプタ、使用のテレメトリー、移行ガイド。
ランタイムでペイロードを検証する必要がありますか?
重要なドメインについては、はい:これはジャンクメッセージを防ぎ、診断を高速化します。
[結果]
スキーマレジストリは、リスクの高い即興からデータの進化を管理可能なプロセスに変えます。一様な相互運用性ルール、自動化された検証、理解可能なバージョン、透明な履歴です。それに添加第一、寛容な読者、二重放出および日没の規律を加えて下さい-そしてあなたの契約は故障および夜の事件なしで、すぐに開発します。