Registro degli schemi e evoluzione dei dati
Perché vuoi un registro degli schemi
Il registro degli schemi è una fonte centralizzata di verità per i contratti dati (API, eventi, flussi, messaggi, storage) che fornisce:- Evoluzione prevedibile: regole di compatibilità e controllo automatico dell'astinenza.
- Ripetitività e trasparenza: cronologia delle versioni di chi/quando/perché ha cambiato.
- Standardizzazione: nomi, formati di errore, campi di traccia, etichette PII.
- Integrazione con CI/CD - Blocca le modifiche breaking prima della produzione.
Il registro collega Protocol-first e la compatibilità contrattuale, rendendo le modifiche veloci e sicure.
Formati e aree di applicazione
JSON Schema: REST/HTTP carichi utili, documenti, configurazioni.
Avro: pneumatici eventi (Kafka/Pulsar), compact/evoluzione attraverso l'ID dei campi.
Protobuf: gRPC/RPC, binario-efficace, tag rigorosi.
SDL: schema di tipi e direttive, evoluzione attraverso «@ deprecated».
SQL DDL come artefatto: fissiamo le rappresentazioni contratte (ad esempio vetrine esterne) con cautela.
Modalità di compatibilità
BACKWARD - I nuovi schemi leggono i vecchi dati/messaggi. Adatto per un produttore che estende payload additivo.
FORWARD - I vecchi consumatori leggono correttamente i nuovi dati (richiede tolerant reader).
FULL combina entrambi (più rigoroso, più conveniente per i contratti pubblici).
NONE - Senza controllo - solo per scudi di sabbia.
- Events: più spesso BACKWARD (il produttore espande payload opzionalmente).
- API pubbliche: FULL o BACKWARD + tolerant reader rigoroso sui clienti.
- Prototipi interni: temporaneamente NONE, ma non trunk.
Modifiche sicure (additive) vs. pericolose
Additivi (OK):- Aggiunge un campo/tipo facoltativo.
- Estensione enum con nuovi valori (con tolerant reader).
- Aggiunge una proiezione/evento alternativa ('.enriched').
- Alleggerimento dei limiti (« », «massimo», ma non ).
- Rimuove o rinomina i campi o ne modifica il tipo o l'obbligatorietà.
- Modifica la semantica degli stati/codec/ordine nei flussi.
- Riutilizza i tag protobuf.
- Cambia la chiave di partizionamento negli eventi.
Organizzazione del Registro di sistema
Neiming e indirizzo
Gruppi/spazi: 'payments', 'kyc', 'audit'.
I nomi sono «payment». authorized. v1` (events), `payments. v1. CaptureRequest` (gRPC), `orders. v1. Order` (JSON Schema).
Maggiore nel nome, minore nei metadati/versioni dello schema.
Metadati
"owner", "domain", "slas" (SLO/SLA), "sicurezza. tier` (PII/PCI), `retention`, `compatibility_mode`, `sunset`, `changelog`.
Gestione del ciclo di vita
Draft → Review → Approved → Released → Deprecated → Sunset.
Validatori/Linter automatici, design-review manuale (API Guild), release note.
Integrazione con CI/CD
1. Pre-commit - Lenti locali (Spectral/Buf/Avro tools).
2. PR-pipline: schema-differf controllo compatibility mode Blocchiamo il breaking.
3. Artifact publish: un po'di schema coerente nel Registro di sistema + generazione SDK/modelli.
4. Runtime-guard (opzionale): il gateway/produttore valuta payload contro lo schema attuale.
- `openapi-diff --fail-on-breaking`
- `buf breaking --against
` - `avro-compat --mode BACKWARD`
- generazione di golden sample e test CDC.
Evoluzione degli schemi: pratiche
Additive-first: новые поля — `optional/nullable` (JSON), `optional` (proto3), default в Avro.
Il modello della piramide inversa è stabile, l'arricchimento è vicino e opzionale.
Dual-emit/dual-write per major: in parallelo pubblichiamo v1 e v2.
Piano Sunset: date, utilizzo, avvisi, adattatori.
Tolerant reader - I client ignorano i campi sconosciuti e gestiscono correttamente i nuovi enum.
Esempi di schemi e controlli
JSON Schema (frammento, campo additivo)
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 (default per la compatibilità)
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 (non utilizzare i tag)
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
Registro eventi e partizionamento
Denominazione eventi: 'domain. action. v{major}` (`payment. captured. v1`).
La chiave di partitura è parte del contratto ('payment _ id', 'user _ id').
Core vs Entriched: ".v1" (kernel) e ".enriched. v1 '(parti).
Compatibilità nel registro: modalità a livello di argomento/tipo; CI rifiuta modifiche incompatibili.
Gestione delle migrazioni
Expand → Migrate → Contract (REST/gRPC):1. Aggiungere campi/tabelle 2) Iniziare a scrivere/leggere nuovi campi; 3) rimuovere il vecchio dopo sunset.
- Dual-emit (Events): parallelo a «v1 »/« v2», migrazione di notebook/proiezioni, quindi rimozione di «v1».
- Replay: ridisegna le proiezioni dal cavo al nuovo schema (solo se compatibili e migranti).
- Adattatori gateway/proxy che tradurranno «v1↔v2» per i clienti complessi.
Sicurezza e compilazione
Etichette PII/PCI in diagramma: «x-pii: true», «x-sensitivity: high».
Criteri di accesso: chi può pubblicare o modificare gli schemi (RBAC), firmare i comunicati.
Crittografia - Firma delle versioni degli schemi, registri di verifica non modificabili (WORM).
Diritto all'oblio: specificare i campi che richiedono crittografia/crittografia-cancellazione; guidance nel registro.
Osservazione e verifica
Dashboard: numero di modifiche, tipi (minor/major), percentuale di PR rifiutati, utilizzo di versioni.
Controllo trail - Chi ha modificato lo schema, collegamenti a PR/ADR, rilascio collegato.
Metriche runtime: percentuale di messaggi non convalidati Incidenti di compatibilità.
Strumenti (stack approssimativo)
OpenAPI/JSON Schema: Spectral, OpenAPI Diff, Schemathesis.
Protobuf/gRPC: Buf, buf-breaking, protoc linters.
Avro/Events: Confluent/Redpanda Schema Registry, Avro-tools, Karapace.
GraphQL: GraphQL Inspector, GraphQL Codegen.
Registri/cataloghi: Artifact Registry, Git-based registry, Backstage Catalog, custom UI.
Documentazione: Redocly/Stoplight, Swagger-UI, GraphiQL.
Antipattern
Swagger-wash: lo schema non riflette la realtà del servizio (o viceversa).
Controllo di compatibilità disattivato, il → si sta rompendo.
Riutilizzo dei tag protobuf - Distruzione silenziosa dei dati.
Un'unica modalità di compatibilità per tutto, con domini diversi che richiedono modalità diverse.
CDC crude come schemi pubblici: fuga di modelli di database verso l'esterno, impossibilità di evoluzione.
Assegno foglio di implementazione
- Formato degli artefatti e compatibility mode definiti per dominio.
- I linter e gli schema-differf sono configurati in CI, il PR viene bloccato durante il breaking.
- Attivato tolerant reader nei clienti; 'additionalProperties=true' (se necessario).
- Le modifiche maggiori passano attraverso RFC/ADR, ci sono un piano sunset e dual-emit/dual-write.
- Schemi contrassegnati con PII/PCI e livelli di accesso; controllo attivato.
- Dashboard per l'utilizzo di versioni e errori di compatibilità.
- La generazione di SDK/modelli dal Registro di sistema fa parte del pipeline.
- Documentazione e golden sample aggiornati automaticamente.
FAQ
È possibile mantenere gli schemi in Git senza registro?
Sì, ma il Registro di sistema aggiunge API compatibilità, ricerca, metadati, criteri centralizzati e convalida on-the-fly. L'opzione migliore è Git come storage + UI/criteri sopra.
Come selezionare la modalità di compatibilità?
Se il produttore estende payload - BACKWARD. Per API/SDK pubblica - FULL. Per i prototipi veloci è temporaneamente NONE (non trunk).
Cosa fare se serve astinenza?
Prepariamo v2: dual-emit/dual-run, sunset-data, adattatori, telemetria d'uso, gate migratorie.
Dobbiamo controllare i payload in un rate?
Per i domini critici, sì, impedisce i messaggi «spazzatura» e accelera la diagnosi.
Totale
Il registro degli schemi trasforma l'evoluzione dei dati da un'improvvisazione rischiosa a un processo gestito: regole di compatibilità unificate, controlli automatici, versioni comprensibili e una storia trasparente. Aggiungete la disciplina additive-first, tolerant reader, dual-emit e sunset - e i vostri contratti evolveranno rapidamente, senza astinenza o incidenti notturni.