GH GambleHub

Teste de contrato

1) Onde aplicar os contratos

HTTP REST/JSON: recursos, paginação, filtros, idempotação, códigos de erro.
gRPC/Protobuf: tipos de mensagens, estatais, semântica 'deadline', backward-compat v.proto.
GraphQL: esquemas, não-null, diretrizes, parafusos em campos.
Mensagens/striptease (Kafka/Pulsar/SQS): circuitos event (Avro/JSON/Protobuf), chaves de partilha, ordem, chaves idimpotentes.
SDK/bibliotecas internas: funções públicas/exceções/contratos de desempenho.


2) Modelo CDC: papéis e artefatos

O consumidor publica o contrato de espera (solicitações/respostas, jogos de tipo, invariantes).
O fornecedor revisa os contratos contra o seu serviço/adaptador/handler 'ov.
O corretor de contratos (Pact Broker/Backstage/artefacto-repo) armazena versões, marcas de formatação ('prod', 'staging', 'canary') e matriz de compatibilidade 'consumer @ v → provider @ v'.
A política de lançamento é proibida quando qualquer contrato prod-relevante for violado.


3) O que fixar no contrato (HTTP exemplo)

Mínimo:
  • Método/caminho/parâmetros/cabeçalho (afixado auth, chave idempotal).
  • Corpo e jogos típicos (tipo/formato/regexp/faixa).
  • Códigos e estrutura de erro; estáveis 'error _ código'.
  • Invariantes semânticos: triagem, exclusividade, monotonia 'created _ at'.
  • Espera não unificada (opcional): p95, limite de tamanho, cabeçalhos rate-limit.
Fatia de contrato (simplificado):
json
{
"interaction": "GET /v1/users/{id}",
"request": { "method": "GET", "path": "/v1/users/123", "headers": {"Accept":"application/json"} },
"matchers": {
"response.body.id": "type:number",
"response.body.email": "regex:^.+@.+\\..+$",
"response.body.created_at": "format:rfc3339"
},
"response": {
"status": 200,
"headers": {"Content-Type":"application/json"},
"body": {"id": 123, "email": "alice@example.com", "created_at": "2025-10-31T12:00:00Z"}
},
"error_cases": [
{
"name":"not_found",
"request":{"path":"/v1/users/9999"},
"response":{"status":404, "body":{"error_code":"USER_NOT_FOUND"}}
}
]
}

4) Contratos de eventos (event-driven)

Esquema de evento: «tipo», «versão», «id», «occurred _ at _ utc», «producer», «subject», «payload».
Invariantes: imutabilidade 'id' e idempotidade por '(tipo, id)', ordem dentro da chave de partição, monotonia 'sequence'.
Schema Registry: armazena a evolução e as regras de compatibilidade (backward/forward/full).
Teste de contrato do Consumer: replica eventos dourados e fases negativas (campos desconhecidos, nullable).

Exemplo de esquema Avro (fatia):
json
{
"type":"record","name":"UserRegistered","namespace":"events.v1",
"fields":[
{"name":"id","type":"string"},
{"name":"occurred_at_utc","type":{"type":"long","logicalType":"timestamp-millis"}},
{"name":"email","type":"string"},
{"name":"marketing_opt_in","type":["null","boolean"],"default":null}
]
}

5) Evolução e compatibilidade

Versões dos contratos: semântica 'MAJOR. MINOR. PATCH '(MAJOR - Quebra).

Regras para o REST:
  • Não rompa: não remova campos, não mude o tipo/valor de 'erro _ código'.
  • Adicione campos opcionais em default; novos endpoint em vez de magia.
  • Decolagem: anúncio, suporte paralelo, remoção por métricas.
  • GraphQL: campos apenas adicionar, não-null digitar através de fases; diretrizes de depredação.
  • gRPC/Proto: não reutilizar números de campos; apenas adicionar novos com optional.
  • Events: esquema 'vN'; Os conceituadores são obrigados a ignorar campos desconhecidos (leniência).

6) Verificações negativas e invariantes

Negative: tipos inválidos, valores não permitidos, parâmetros conflitantes, excesso de limites.
Invariants: triagem de respostas, exclusividade de 'id', correção de 'next _ cursor', estabilidade de resposta idumpotente quando repetida.
Os contratos dos aspectos temporários: 'created _ at' RFC3339/UTC, a projeção correta do dia local não faz parte do contrato de transporte - é levada para os invariantes de negócios.


7) Geração de stab e desenvolvimento local

A partir dos contratos são gerados manadas do provedor para o desenvolvimento do consumidor.
Para os eventos, geradores de mensagens «validas/fronteiras» no esquema.
As manadas são marcadas com a versão do contrato e a data de montagem; Não é permitido publicar em proda.


8) Incorporação a CI/CD (arbitragem-pipline)

1. Consumer CI:

Lint/montagem → geração de contratos → unit/contrato-teste → publicação em contract-broker (tag: 'consumer @ 1. 7. 0`).

2. Provider CI:

Levantar o serviço localmente/em um contêiner → o fetch de contratos relevantes ('prod '/' staging') → verificar → publicar o status em broker.

3. Release Gate:

O deplay do provedor é bloqueado se houver contratos não cumpridos.

4. Nightly Matrix:

Matriz de compatibilidade 'consumer versions x provider versions'; relatórios e ansiedades.


9) Exemplos de práticas de domínios

9. 1 REST: paginação com cursores (invariante contratado)

A resposta contém 'items []', 'next _ cursor' (nullable), 'limit', 'total' (opcional).
Invariantes: 'len (items) ≤ limit', recall com o mesmo 'cursor' → conjunto idempotante.
Erro se «cursor» e «page» foram definidos ao mesmo tempo.

9. 2 Idempotidade POST

O contrato requer o título «Idempotency-Key».
Invariante: Uma nova consulta com a mesma chave devolve o mesmo 'id '/status.

9. 3 Eventos: garantias de ordem

A chave de partilha do contrato é 'partition _ key = user _ id'.
Invariante: 'sequence' aumenta monótono dentro da chave; É obrigatório processar as repetições.


10) Segurança e privacidade nos contratos

Não incluir PDN/segredos em exemplos - apenas sintético.
Capturar cabeçalhos de segurança obrigatórios: «Autodeclaração», «X-Mensagem», «Replay-Prevision».
Para webhooks, contrato de assinatura e resposta '2xx '/retrações.
No logs de testes, camuflar campos sensíveis.


11) Ferramentas

Pact/Pactflow/Pact Broker - HTTP/Mensagem contratos, matriz de compatibilidade.
OpenAPI/AsyncAPI - especificações + geradores de teste (Dredd, Schemathesis).
Karate/REST Assured - Verificações cenais de contratos da REST.
Protobuf/gRPC - 'buf', 'protolint', testes de compatibilidade; Schema Registry para Avro/JSON/Proto em fluxo.
Testes de Conformance para GraphQL (graphql-compat), testes de circuito snapshot.


12) Pseudocode de verificação do provedor (simplificado)

python def verify_contract(provider, contract):
for case in contract["cases"]:
req = build_request(case["request"])
res = provider.handle(req) # локально/контейнер assert match_status(res.status, case["response"]["status"])
assert match_headers(res.headers, case["response"].get("headers", {}))
assert match_body(res.body, case["matchers"], allow_extra_fields=True)
for neg in contract.get("error_cases", []):
res = provider.handle(build_request(neg["request"]))
assert res.status == neg["response"]["status"]
assert res.json.get("error_code") == neg["response"]["body"]["error_code"]

13) Anti-pattern

«Screenshots Postman é um contrato»: nenhuma versão/matchers típicos/validação automática.
Oversnaping: O contrato fixa valores precisos em vez de tipos/pattern → baixas falsas.
Um contrato comum para diferentes regiões/canais: ignora variabilidade (bandeiras, regras geo).
Contratos sem corretor/matriz: Não é possível saber quais versões são compatíveis.
Aposta em e2e em vez de contratos: lento, caro, instável.
Nenhuma mala negativa/invariante: apenas a faixa verde é testada.


14) Observabilidade e exploração

Exportar status para broker + dashboard «health contratos».
Alerts: Novas baixas do provedor contra 'prod', crescimento de 'unknown field' nos eventos.
Traçado: 'contract _ id', 'version', 'decision _ id' nos logs de verificação.


15) Processo de despoluição

1. Adicionar campo/endpoint (não quebra).
2. Marcar o antigo como 'deprecated' na especificação, anunciar o prazo.
3. Monitorar os consumidores através de logs/corretores; guidas migratórias.
4. Incluir deny «shadow» em um stage (dry-run) e, em seguida, enforce.
5. Remover após zero uso e confirmação de compatibilidade.


16) Folha de cheque do arquiteto

1. Os consumidores e os proprietários são identificados? Os contratos são versionizados?
2. Há um broker e uma matriz de compatibilidade com marcas de ambientes?
3. O contrato inclui negativos e invariantes (idiempotidade, cursores, triagem)?
4. O modo de compatibilidade do Schema Registry está configurado para eventos?
5. O Pipeline bloqueia o lançamento do provedor quando os contratos de prod são violados?
6. Descrito o processo de depredação e a política de evolução?
7. Geram-se manadas de contratos, há geradores de eventos locais?
8. Camuflagem de PD e cabeçalhos de segurança obrigatórios documentados?
9. As métricas/alertas estão conectadas, há relatórios de drift?
10. Os contratos são verificados em CI em ambas as partes (consumer e provider)?


Conclusão

Os testes contratuais transferem a «verdade» sobre as interações em artefatos versionáveis e tornam a integração previsível. O CDC, o corretor de contratos e a disciplina de evolução dos esquemas substituem as «surpresas quebrantes» por um processo controlado: verificações rápidas, invariantes claros e compatibilidade transparente de versões. Isso reduz o custo e2e, acelera os lançamentos e melhora a qualidade de toda a plataforma.

Contact

Entrar em contacto

Contacte-nos para qualquer questão ou necessidade de apoio.Estamos sempre prontos para ajudar!

Iniciar integração

O Email é obrigatório. Telegram ou WhatsApp — opcionais.

O seu nome opcional
Email opcional
Assunto opcional
Mensagem opcional
Telegram opcional
@
Se indicar Telegram — responderemos também por lá.
WhatsApp opcional
Formato: +indicativo e número (ex.: +351XXXXXXXXX).

Ao clicar, concorda com o tratamento dos seus dados.