Compatibilidade contratual API
Por que precisa de compatibilidade contratual
Compatibilidade contratual é a capacidade da API de evoluir sem quebrar as integrações existentes. A API em crescimento muda com mais frequência de código de cliente; compatibilidade permite a produção de fici iterativamente, sem «grandes deslocamentos».
A ideia-chave é que o contrato é primário, as alterações seguem as regras de compatibilidade e são verificadas automaticamente.
Conceitos básicos
Contrato - especificação formal de interface: recursos/métodos/eventos, esquemas de dados, códigos de erro, limites, SLA, requisitos de segurança.
O provedor (provider) é o dono da API. O consumidor (consumer) é cliente/integração.
- Backward: O novo fornecedor trabalha com consumidores antigos.
- Forward: um fornecedor antigo trabalha com novos consumidores (normalmente alcançado por «leitores tolerantes»).
- Full: o backward e o forward (a opção mais forte) foram cumpridos.
- Adutora - Adição de itens opcionais sem quebrar os itens existentes.
Política de versionização
Semantic Versioning (recomendado):- MAJOR - Alterações quebrantes (somente quando a nova linha API é lançada: '/v2 ',' service. v2`).
- MENOR - Alterações aditivas (novos campos/métodos opcionais).
- PATCH - correções sem alteração de contrato.
- Deprecation Policy: declaração de itens obsoletos, janela de suporte (sunset), avisos em cabeçalhos/metadados, plano de retirada.
Alterações seguras vs perigosas
Seguro (normalmente backward-compatível)
Adicione um campo opcional ao JSON/Protobuf/Avro.
Adicione um novo endpoint/método/evento.
Expansão enum com novos valores se os consumidores são tolerantes com valores desconhecidos.
Aumentar os limites (por exemplo, 'maxItems') sem endurecer os limites mínimos.
Adicione nullable com default correto.
Altere o texto das descrições/exemplos.
Perigosos (quebra de compatibilidade)
Renomear ou remover campos, alterar seu tipo ou obrigatoriedade.
Mudar a semântica de status/erro (por exemplo, havia «200», tornou-se «204» ou «404»).
Altera o formato de ID (UUID → int).
Endurecimento da validação (mínimo/pattern) sem versão.
Mudança de ordem e estrutura em gRPC striptease/evento.
Reutilizar números de formatação em Protobuf para novos campos.
Compatibilidade com estilos de interação
REST/HTTP + JSON Schema
Adutora: Marcamos novos campos como 'optional '/' nullable'.
Tolerant Reader em um cliente: ignorar campos desconhecidos; Não depender da ordem.
Versioning: maior - no caminho ('/v2 ') ou no midiático (' aplicação/vnd. example. v2+json`).
ETAG/If-Match: para updates seguros sem corridas.
Erro: formato único («tipo», «código», «title», «detail», «trace _ id»), não altere o valor de «código» sem o maior.
Paginação: os cursores são preferíveis a offset; adicione os campos 'next _ cursor', e não altere o significado dos que existem.
gRPC / Protobuf
A numeração de formatação está inalterada. As marcas de formatação remotas não serão reutilizadas.
Os novos campos são 'optional '/' repeated' com default razoável no servidor.
Não altere a ordem e obrigatoriedade das mensagens em streaming-RPC.
Os estados de erro são estáveis ('INVALID _ ARGUMENT', 'FAILED _ PRECISION', etc.); a nova semântica é uma nova versão do método/serviço.
Event-driven (Kafka/NATS/Pulsar) + Avro/JSON Schema
Nome de evento: 'domain. action. v{major}`.
Novos campos - opcionais; selecione o núcleo e o enriquecimento ('.enriched').
Maiúsculas: regras de compatibilidade (BACKWARD/FORWARD/FULL) sobre o tema/evento.
A extensão enum é permitida com o tolerant reader do lado dos consumidores.
Mudar a chave de partilha/ordem para o dispositivo = alterações de quebra.
GraphQL
Adicionar campos/tipos é seguro; remover/renomear - somente através de @ deprecated e da janela de migração.
Não altere os tipos/não nullable sem o maior.
Controle o complexity/depth - os limites fazem parte do contrato.
Patternos de Evolução Sustentável
Aditivo-first: expanda sem quebrar.
Capability negotion: os clientes informam que suportam (cabeçalhos/parâmetros/acordos) e o servidor se ajusta.
Limites do contrato: fixe o MGC (contrato mínimo de garantia) e separe as extensões (modelo de pirâmide inversa).
Tolerance by default: os clientes ignoram os valores desconhecidos do enum (fallback).
Dual-write/Dual-emit: Quando tiver alterações maiores, libere «v1» e «v2» em paralelo.
Sunset headers/Events: avise-se com antecedência do levantamento.
Governance e automação
Lentes API:- OpenAPI/Spectral: denominação, paginação, códigos de erro, formatos de campo.
- Buf/Protobuf: Impede a reutilização de marcas de formatação, notação de pacotes.
- AsyncAPI/Schema Registry: compatibilidade de circuitos no nível CI.
- Catálogo de contratos (SSOT): Registro centralizado de esquemas/versões com histórico de difusões.
- API Guild: guild/comitê que adota regras, modelos e alterações.
- Mudança Management: RFC/ADR, release de notas, guias de migração.
Testes de compatibilidade
Schema-diff em CI: bloqueamos alterações de spack quebrantes (OpenAPI-diff, Buf breaking, SR compatibility).
Consumer-Driven Contracts (CDC): Pact/similares - verificação do fornecedor contra contratos de consumidores específicos.
Golden sample: perguntas de referência/respostas e eventos para regresso.
E2E Canary: rotação em parte do tráfego/grupos de consórcios individuais.
Chaos/latency: verificação de temporizações/retrações - a alteração do latency-SLO é considerada uma mudança no contrato.
Migração e Deprekate
1. Declare o deprekate: selecione o item, especifique a data sunset e a alternativa.
2. Suporte o período de compatibilidade dual-write/dual-emit, pontes, adaptadores.
3. Colecione telemetria, quem mais usa o antigo?
4. Comunicações: emails, notas de lançamento, estandes de teste.
5. Levantamento: após a janela, remoção com lançamento fixo.
Exemplos de alterações
REST
Foi:json
{ "id":"p1", "status":"authorized" }
Tornou-se (aditivo, seguro):
json
{ "id":"p1", "status":"authorized", "risk_score": 0. 12 }
Os clientes que ignoram campos desconhecidos não quebram.
Protobuf
proto message Payment {
string id = 1;
string status = 2; // don't change tag numbers optional double risk_score = 3; // additive
}
Event
`payment. authorized. v1 '(núcleo) +' payment. enriched. v1 '(enriquecimento). Os consumidores da via crítica leem o núcleo e não dependem de enriquecimento.
Antipattern
Swagger-wash: a especificação está formalmente disponível, mas o comportamento do serviço difere dela.
Breaking by stealth: Alterou o tipo/status/formato sem uma nova versão ou janela de migração.
Eventos CDC crus como um contrato público, fuga de esquemas de base de dados, impossibilidade de evolução.
Cliente rígido: cai em campos/valores desconhecidos; falta do tolerant reader.
Reutilização de marcas protobuf: corrupção silenciosa de dados.
Latência como «não-contínua»: inesperadamente, os p95 foram alongados - os consumidores quebram por temporais.
Folha de cheque de compatibilidade (antes do merj)
- As alterações são aditivas (ou a versão maior está preparada).
- Os linters/cheques diff foram ultrapassados, as regras de compatibilidade são verdes.
- Erros/códigos/estatais não alteraram a semântica.
- Enum expandidos sem que os valores antigos sejam excluídos; clientes - tolerant.
- Os limites do MGC estão inalterados.
- Os exemplos/documentação/SDK foram atualizados.
- Para o maior - plano dual-write/dual-emit, sunset-data, plano comm.
- Os testes CDC/Golden/E2E foram concluídos.
FAQ
Em que é que o backward difere da compatibilidade forward?
Backward - Os novos servidores não quebram clientes antigos. Forward - novos clientes não quebram em servidores antigos (através de tolerant reader e default cuidadoso).
Quando é que fazes «/v2 »?
Quando invariantes/semânticos mudam, campos/métodos são removidos, um novo modelo de segurança é necessário - é mais fácil e honesto executar uma nova linha.
É possível viver sem Schema Registry/linter?
Teoricamente, sim, são quase regravações frequentes e quebras «escondidas». A automação é rentável.
Enum pode ser expandido?
Sim, se os clientes processarem corretamente valores desconhecidos (fallback/ignore). Senão, maior.
Resultado
Compatibilidade contratual - regras + disciplina + automação. Projete de forma aditiva, versionize as alterações de quebra, aplique o tolerant reader, verifique os difs e CDC, planeje o deprekate. Assim, as APIs podem evoluir rapidamente, e as integrações podem permanecer estáveis.