Registro de esquemas e evolução dos dados
Para quê um registro de esquema
O registro de esquemas é uma fonte centralizada de verdade para contratos de dados (API, eventos, fluxos, mensagens, armazenamento) que fornece:- Evolução previsível: regras de compatibilidade e verificação automática de quebra.
- Repetição e transparência: histórico de versões de quem/quando/porquê mudou.
- Normalização: nomes unificados, formatos de erro, campos de rastreamento, marcas PII.
- Integração com CI/CD: bloqueio de alterações breaking antes da produção.
O registro liga Protocol-first e compatibilidade contratual, tornando as alterações rápidas e seguras.
Formatos e aplicações
JSON Schema: REST/HTTP cargas úteis, documentos, configurações.
Avro: pneus de evento (Kafka/Pulsar), compacto/evolução via ID de campo.
Protobuf: gRPC/RPC, binário-eficiente, marcas de formatação rigorosas.
SDL: padrão de tipos e diretrizes, evolução através de «@ deprecated».
SQL DDL como artefato: Captamos apresentações contratuais (como vitrines externas) com cautela.
Modos de compatibilidade
BACKWARD: Novos circuitos leem dados/mensagens antigos. Adequado para um produtor que expande payload aditivo.
FORWARD: Os consumidores antigos leem corretamente os novos dados (exigindo tolerant reader).
FULL: combina ambos (mais rigoroso, mais fácil para contratos públicos).
NONE: Sem verificação, apenas para canhões de areia.
- Events: com mais frequência BACKWARD (o produtor está expandindo payload opcionalmente).
- API público: FULL ou BACKWARD + tolerant reader rigoroso nos clientes.
- Protótipos internos: temporariamente NONE, mas não em trunk.
Mudanças seguras (adutoras) vs. perigosas
Aditivos (OK):- Adicione um campo/tipo opcional.
- Extensão enum com novos valores (com tolerant reader).
- Adicione uma projeção/evento alternativa ('.enriched').
- Redução das limitações («minLength», «máximo» ↑, mas não ↓).
- Remova ou renomeia os campos ou altera o seu tipo/obrigatoriedade.
- Altera a semântica de estatais/codecs/ordem nos fluxos.
- Reutilizar marcas protobuf.
- Altere a chave de partilha dos eventos.
Organizar registro
Nayming e direcionamento
Grupos/espaços: 'payments', 'kyc', 'auditoria'.
Os nomes são 'payment. authorized. v1` (events), `payments. v1. CaptureRequest` (gRPC), `orders. v1. Order` (JSON Schema).
Maior em nome, menor em metadados/versão do esquema.
Metadados
'owner' (comando), 'domain', 'slas' (SLO/SLA), 'security'. tier` (PII/PCI), `retention`, `compatibility_mode`, `sunset`, `changelog`.
Gerenciamento do ciclo de vida
Draft → Review → Approved → Released → Deprecated → Sunset.
Validadores/linters automáticos, design-review manual (API Guild), release notas.
Integração em CI/CD
1. Pré-commit: Linters locais (Spectral/Buf/Avro tools).
2. PR-Pipeline: schema-diff → Verificação de compatibilidade de moda; bloqueamos o breaking.
3. Artifact publish: um poço de esquema coerente no registro + geração de SDK/modelos.
4. Runtime-guard (opcional): O porteiro/produtor valida o payload contra o padrão atual.
- `openapi-diff --fail-on-breaking`
- `buf breaking --against
` - `avro-compat --mode BACKWARD`
- geração de golden sample e testes CDC.
Evolução dos circuitos: práticas
Additive-first: новые поля — `optional/nullable` (JSON), `optional` (proto3), default в Avro.
O modelo da pirâmide inversa é estável, o enriquecimento é próximo e opcional.
Dual-emit/dual-write para major: paralelamente publicamos 'v1' e 'v2'.
Plano sunset: datas, uso, avisos, adaptadores.
Tolerant reader: Os clientes ignoram campos desconhecidos e processam corretamente novos enum.
Exemplos de esquemas e verificações
JSON Schema (fragmento, campo adutor)
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 para compatibilidade)
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 (não use marcas de formatação)
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 de eventos e partitização
Nome de evento: 'domain. action. v{major}` (`payment. captured. v1`).
A chave de partilha é parte do contrato ('payment _ id', 'user _ id').
Core vs Enriched: '.v1' (núcleo) e '.enriched. v1 '(peças).
Compatibilidade de registro: modos de tópico/tipo; A CI falha alterações incompatíveis.
Gerenciamento de migrações
Expand → Migrate → Contract (REST/gRPC):1. adicionar campos/tabelas; 2) começar a escrever/ler novos campos; 3) remover o antigo após sunset.
- Dual-emit (Events): paralelo a 'v1 '/' v2', migração de consoantes/projeções, seguida de retirada de 'v1'.
- Replay: Recorrente projeções do logo para o novo padrão (somente com compatibilidade e migradores).
- Adaptadores: gateway/proxy que traduzem 'v1↔v2' para clientes complexos.
Segurança e Complacência
Marcas PII/PCI no padrão: 'x-pii: true', 'x-sensividade: high'.
Políticas de acesso: quem pode publicar/alterar esquemas (RBAC), assinar lançamentos.
Criptografia: assinatura de versões de diagramas, registros de auditoria imutáveis (WORM).
Direito ao esquecimento: especifique os campos que exigem criptografia/cripto-apagado; lidance no registro.
Observação e auditoria
Dashboards: número de alterações, tipos (menor/maior), percentual de PR rejeitado, uso de versões.
Trailer de auditoria: quem alterou o esquema, links para PR/ADR, lançamento associado.
Métricas Runtime: porcentagem de mensagens que não foram validadas; incidentes de compatibilidade.
Ferramentas (amostra de pilha)
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.
Registros/diretórios: Artifact Registry, Git-based registry, Backstage Catalog, custom UI.
Documentação: Redocly/Stoplight, Swagger-UI, GraphiQL.
Antipattern
Swagger-wash: o padrão não reflete a realidade do serviço (ou vice-versa).
Verificação de compatibilidade desativada, «preciso de urgência».
Reutilizar marcas protobuf: quebra silenciosa de dados.
Um único modo de compatibilidade «para tudo»: domínios diferentes exigem modos diferentes.
CDC crus como esquemas públicos, vazamento do modelo BD para fora, impossibilidade de evolução.
Folha de cheque de implementação
- O formato de artefatos e de compatibilidade de domínios foi definido.
- Linterners configurados e schema-diff configurados em CI, PR bloqueado em breaking.
- É ativado o tolerant reader nos clientes; 'additionalProperties=true' (se apropriado).
- As alterações maiores passam por RFC/ADR, há um plano sunset e dual-emit/dual-write.
- Os circuitos estão marcados com PII/PCI e níveis de acesso; a auditoria está ativada.
- Dashboards de uso de versões e falhas de compatibilidade.
- A geração de SDK/modelos a partir do registro faz parte do pipline.
- Documentação e golden sample atualizados automaticamente.
FAQ
É possível armazenar esquemas no Git sem registro?
Sim, mas o registro adiciona API de compatibilidade, busca, metadados, política centralizada e validação on-the-fly. A melhor opção é Git como armazenamento + UI/políticas acima.
Como escolher o modo de compatibilidade?
Veja a direção da mudança: se o produtor estender o payload - BACKWARD. Para API pública/SDK - FULL. Para protótipos rápidos - temporariamente NONE (não em trunk).
O que fazer se for necessário?
Preparamos v2: dual-emit/dual-run, sunset-datas, adaptadores, telemetria de uso, guindastes migratórios.
É preciso validar o payload no RAT?
Para domínios críticos, sim, isso impede mensagens de lixo e acelera o diagnóstico.
Resultado
O registro de esquemas transforma a evolução dos dados de uma improvisação arriscada em um processo controlado, como regras de compatibilidade, verificações automáticas, versões compreensíveis e um histórico transparente. Adicione-lhe a disciplina de aditivo-first, tolerant reader, dual-emit e sunset - e seus contratos vão evoluir rapidamente, sem quebras ou incidentes noturnos.