Capstone: Build a Java Contract Governance Platform for APIs and Events
Learn Java API Contract Engineering, Event Contract Engineering & Schema Governance - Part 032
Capstone project for top-tier Java contract engineers: build a contract governance platform for OpenAPI, AsyncAPI, Avro, Protobuf, JSON Schema, Kafka topics, schema registry, catalog, diff, CI gates, runtime enforcement, and observability.
Part 032 — Capstone: Build a Java Contract Governance Platform for APIs and Events
Tujuan Pembelajaran
Ini adalah final part.
Capstone ini menggabungkan seluruh seri menjadi satu proyek besar:
Build a Java Contract Governance Platform for API contracts, event contracts, schema governance, compatibility, catalog, runtime enforcement, and observability.
Tujuannya bukan membuat toy project. Tujuannya membuat blueprint platform engineering yang realistis untuk enterprise.
Setelah menyelesaikan capstone ini, kamu harus mampu menunjukkan skill top-tier dalam:
- contract-first architecture;
- API/event/schema governance;
- Java platform engineering;
- schema registry integration;
- OpenAPI/AsyncAPI processing;
- Avro/Protobuf/JSON Schema handling;
- Kafka contract modeling;
- diff and compatibility classification;
- CI/CD governance gates;
- catalog and lineage;
- runtime enforcement;
- observability and incident response;
- multi-team operating model.
1. Capstone Goal
Build platform named:
ContractHub
ContractHub provides:
- contract repository ingestion;
- OpenAPI validation and diff;
- AsyncAPI validation and diff;
- Avro compatibility checks;
- Protobuf breaking-change checks;
- JSON Schema validation/diff;
- Kafka topic contract governance;
- policy-as-code engine;
- schema registry integration;
- catalog API and UI-ready data model;
- consumer registration;
- lifecycle management;
- CI report generation;
- runtime violation ingestion;
- governance dashboards;
- incident runbook links.
2. Target Architecture
Core modules:
contracthub/
├── contracthub-core
├── contracthub-openapi
├── contracthub-asyncapi
├── contracthub-avro
├── contracthub-protobuf
├── contracthub-jsonschema
├── contracthub-kafka
├── contracthub-policy
├── contracthub-registry
├── contracthub-catalog
├── contracthub-runtime
├── contracthub-cli
└── contracthub-app
3. Domain Model
3.1 ContractArtifact
public record ContractArtifact(
ArtifactId id,
ArtifactType type,
String name,
String ownerTeam,
LifecycleState lifecycle,
DataClassification dataClassification,
URI sourceUri,
Instant updatedAt
) {}
ArtifactType:
public enum ArtifactType {
OPENAPI,
ASYNCAPI,
AVRO,
PROTOBUF,
JSON_SCHEMA,
KAFKA_TOPIC,
EVENT_TYPE,
API_OPERATION
}
Lifecycle:
public enum LifecycleState {
DRAFT,
IN_REVIEW,
APPROVED,
PUBLISHED,
STABLE,
EXPERIMENTAL,
DEPRECATED,
RETIRED,
ARCHIVED
}
3.2 ContractChange
public record ContractChange(
ChangeId id,
ArtifactId artifactId,
ArtifactType artifactType,
String path,
ChangeType changeType,
JsonNode oldValue,
JsonNode newValue,
CompatibilityClass compatibilityClass,
Confidence confidence,
List<String> notes
) {}
CompatibilityClass:
public enum CompatibilityClass {
SAFE,
DANGEROUS,
BREAKING,
SEMANTIC_REVIEW_REQUIRED,
BLOCKER
}
3.3 GovernanceDecision
public record GovernanceDecision(
boolean allowed,
RiskBand riskBand,
List<PolicyViolation> violations,
List<RequiredAction> requiredActions,
List<ReviewerRole> requiredReviewers
) {}
4. Repository Layout for Demo
demo-contracts/
├── openapi/
│ └── customer-api.yaml
├── asyncapi/
│ └── case-events.yaml
├── schemas/
│ ├── avro/
│ │ └── case/CaseApproved.avsc
│ ├── protobuf/
│ │ └── customer/customer_events.proto
│ └── json-schema/
│ └── customer/CustomerActivated.schema.json
├── kafka/
│ └── topics.yaml
├── lifecycle/
│ └── artifacts.yaml
├── examples/
│ └── case-approved-v1.json
├── decisions/
│ └── CDR-template.md
└── policy/
└── contract-policy.yaml
Use this repo as input for ContractHub CLI.
5. CLI Commands
Build CLI:
contracthub validate ./demo-contracts
contracthub diff ./demo-contracts --baseline ./released-contracts
contracthub check ./demo-contracts --baseline ./released-contracts
contracthub report ./demo-contracts --format markdown
contracthub catalog build ./demo-contracts
Expected output:
Overall risk: HIGH
Violations:
- KAFKA_KEY_CHANGE_REQUIRES_CDR
- AVRO_ADDED_FIELD_WITHOUT_DEFAULT
Required reviewers:
- event-platform
- contract-governance
6. Validation Engine
Interface:
public interface ContractValidator {
ArtifactType supports();
ValidationResult validate(Path artifactPath);
}
ValidationResult:
public record ValidationResult(
ArtifactId artifactId,
boolean valid,
List<ValidationMessage> messages
) {}
ValidationMessage:
public record ValidationMessage(
Severity severity,
String code,
String path,
String message
) {}
Validators:
- OpenApiValidator;
- AsyncApiValidator;
- AvroSchemaValidator;
- ProtobufValidator;
- JsonSchemaValidator;
- KafkaTopicContractValidator;
- LifecycleMetadataValidator.
Minimum behavior:
- parse file;
- ensure required metadata;
- resolve references where possible;
- report actionable errors.
7. Normalizer
Create normalized model.
public interface ContractNormalizer {
ArtifactType supports();
NormalizedArtifact normalize(Path artifactPath);
}
NormalizedArtifact:
public record NormalizedArtifact(
ArtifactId id,
ArtifactType type,
JsonNode canonicalModel,
Map<String, String> metadata
) {}
Canonicalization:
- sort object properties;
- resolve local refs where practical;
- remove non-semantic formatting;
- keep descriptions for semantic hints;
- preserve source paths.
8. Diff Engine
public interface ContractDiffEngine {
List<ContractChange> diff(
NormalizedArtifact baseline,
NormalizedArtifact candidate
);
}
Implement format-specific engines:
- OpenApiDiffEngine;
- AsyncApiDiffEngine;
- AvroDiffEngine;
- ProtobufDiffEngine;
- JsonSchemaDiffEngine;
- KafkaContractDiffEngine;
- LifecycleDiffEngine.
Example rule:
public final class KafkaKeyChangeRule implements DiffRule {
@Override
public Optional<ContractChange> evaluate(JsonNode oldModel, JsonNode newModel) {
String oldKey = oldModel.at("/key/expression").asText(null);
String newKey = newModel.at("/key/expression").asText(null);
if (!Objects.equals(oldKey, newKey)) {
return Optional.of(new ContractChange(
ChangeId.next(),
artifactId,
ArtifactType.KAFKA_TOPIC,
"/key/expression",
ChangeType.KAFKA_KEY_CHANGED,
TextNode.valueOf(oldKey),
TextNode.valueOf(newKey),
CompatibilityClass.BREAKING,
Confidence.HIGH,
List.of("Kafka key change affects partitioning and ordering.")
));
}
return Optional.empty();
}
}
9. Policy Engine
Policy input:
- changes;
- artifact metadata;
- catalog context;
- consumer impact;
- decision records;
- exception records.
Policy output:
- allowed or blocked;
- violations;
- required actions;
- required reviewers;
- risk band.
public interface PolicyEngine {
GovernanceDecision evaluate(PolicyContext context);
}
Example policy:
rules:
- id: KAFKA_KEY_CHANGE_REQUIRES_CDR
when:
changeType: KAFKA_KEY_CHANGED
require:
- decisionRecord
- migrationPlan
- reviewer:event-platform
severity: error
- id: AVRO_ADDED_FIELD_REQUIRES_DEFAULT
when:
changeType: AVRO_FIELD_ADDED_WITHOUT_DEFAULT
severity: blocker
- id: STABLE_ARTIFACT_REQUIRES_OWNER
when:
lifecycle: STABLE
missing: ownerTeam
severity: error
10. Compatibility Engine
public interface CompatibilityChecker {
ArtifactType supports();
CompatibilityResult check(
NormalizedArtifact baseline,
NormalizedArtifact candidate,
CompatibilityMode mode
);
}
Implement minimum rules:
- Avro field added without default;
- Protobuf field number reuse;
- JSON Schema added required property;
- OpenAPI removed path/operation/response field;
- Kafka key/retention change.
Later integrate real libraries and registries.
11. Schema Registry Integration
Interface:
public interface SchemaRegistryGateway {
Optional<RegisteredSchema> findLatest(ArtifactId artifactId);
CompatibilityResult checkCompatibility(ArtifactId artifactId, String schemaContent);
RegisteredSchema register(ArtifactId artifactId, String schemaContent, ArtifactMetadata metadata);
}
Implementation modes:
- mock/in-memory for capstone;
- HTTP adapter for actual registry;
- file-based registry for local demo.
Keep registry interface separate from domain logic.
12. Catalog Module
Catalog entities:
- service;
- API;
- operation;
- event type;
- channel/topic;
- schema artifact;
- consumer;
- lifecycle;
- deprecation record;
- runtime signal.
Catalog API examples:
GET /catalog/artifacts
GET /catalog/events/{eventType}
GET /catalog/topics/{topic}
GET /catalog/consumers/{consumerId}
POST /catalog/consumptions
GET /catalog/impact/{artifactId}
Spring controller sketch:
@RestController
@RequestMapping("/catalog")
public class CatalogController {
private final CatalogService catalogService;
@GetMapping("/events/{eventType}")
public EventCatalogEntry getEvent(@PathVariable String eventType) {
return catalogService.getEvent(eventType);
}
}
13. Runtime Violation Ingestion
Services report violations.
API:
POST /runtime/violations
Body:
{
"violationCode": "EVENT_SCHEMA_INVALID",
"service": "case-projection-service",
"artifactId": "com.acme.case.events.CaseApproved",
"eventType": "CaseApproved",
"topic": "case-events",
"consumerGroup": "case-projection-service",
"schemaRef": "case.CaseApproved:7",
"occurredAt": "2026-06-29T06:00:00Z",
"action": "quarantined"
}
Use this to power dashboards and catalog runtime context.
14. Report Generator
Generate Markdown and JSON.
Markdown structure:
# ContractHub Report
Overall Risk: High
## Summary
Changed artifacts...
## Breaking Changes
...
## Dangerous Changes
...
## Policy Violations
...
## Required Reviewers
...
## Consumer Impact
...
JSON structure for CI:
{
"overallRisk": "HIGH",
"allowed": false,
"changes": [],
"violations": [],
"requiredActions": [],
"requiredReviewers": []
}
15. Minimum Viable Capstone
Build MVP with:
- read contract repo;
- parse lifecycle metadata;
- validate JSON/YAML exists and required metadata;
- implement Kafka topic diff;
- implement Avro added-field-without-default check;
- implement Protobuf field-number reuse check on simplified descriptor model;
- implement OpenAPI removed-path and required-request-field check;
- generate Markdown report;
- expose catalog endpoint for event type;
- ingest runtime violation;
- show simple dashboard JSON.
MVP success:
contracthub check demo-contracts --baseline released-contracts
returns:
BLOCKED: Avro field approvalChannel added without default.
HIGH: Kafka key changed for case-events.
16. Advanced Capstone
Add:
- real OpenAPI parser;
- real AsyncAPI parser;
- schema registry integration;
- Protobuf descriptor diff;
- JSON Schema compatibility analysis;
- consumer inventory;
- risk scoring;
- policy-as-code YAML;
- PR comment integration;
- runtime drift detection from Kafka/admin API;
- metrics dashboards;
- generated Java compile checks;
- deprecation monitor;
- lineage graph.
17. End-to-End Scenarios
Scenario 1 — Safe API Change
Change:
Add optional response field customer.preferredName.
Expected:
- OpenAPI diff detects optional response field added;
- classification SAFE;
- generated client compiles;
- examples updated;
- policy passes;
- report says low risk;
- owner review enough.
Scenario 2 — Dangerous Event Change
Change:
Add enum value MANUAL_REVIEW to KycStatus.
Expected:
- schema diff detects enum added;
- classification DANGEROUS;
- policy requires decision record;
- consumer inventory lists impacted consumers;
- unknown enum tests required;
- report blocks until evidence provided.
Scenario 3 — Breaking Kafka Key Change
Change:
case-events key changes from caseId to eventId.
Expected:
- Kafka diff detects key change;
- classification BREAKING;
- policy requires architecture review and migration plan;
- catalog shows consumers;
- report blocks.
Scenario 4 — Runtime Violation
Runtime sends:
{
"violationCode": "EVENT_SCHEMA_INVALID",
"eventType": "PaymentCaptured",
"topic": "payment-events"
}
Expected:
- violation stored;
- catalog event page shows recent violations;
- dashboard increments;
- owner identified;
- alert created if threshold exceeded;
- runbook link shown.
18. Testing Strategy
18.1 Unit Tests
- parser;
- normalizer;
- diff rules;
- policy rules;
- risk scoring;
- report rendering.
18.2 Integration Tests
- contract repo fixture -> report;
- registry mock integration;
- catalog API;
- runtime violation ingestion;
- Postgres persistence if used.
18.3 Golden Tests
Store expected reports:
fixtures/reports/kafka-key-change.expected.md
Compare generated output to expected.
18.4 Regression Tests from Incidents
Every real contract incident should become a fixture.
19. Suggested Tech Stack
Java platform:
- Java 21+;
- Spring Boot;
- Jackson;
- Maven or Gradle;
- JUnit 5;
- AssertJ;
- Testcontainers;
- Micrometer.
Optional integrations:
- OpenAPI parser;
- AsyncAPI parser/validator;
- Apache Avro;
- Protobuf compiler/descriptor tooling;
- JSON Schema validator;
- Kafka clients;
- schema registry client;
- ArchUnit for enforcing paved-road usage.
Architecture matters more than brand choice.
20. Portfolio Narrative
When explaining this project in interview or promotion packet:
“I built a contract governance platform that parses API/event/schema artifacts, normalizes them, detects structural and operational diffs, classifies compatibility risk, enforces policy-as-code, integrates with schema registry and catalog, and ingests runtime contract violations. It prevents unsafe changes like Avro required field additions, Protobuf tag reuse, Kafka key changes, and undocumented API breaking changes before they reach production.”
This demonstrates senior/platform-level thinking.
21. What Top 1% Looks Like Here
Top-tier engineer does not only know OpenAPI or Kafka.
They can connect:
- API semantics;
- event semantics;
- schema evolution;
- runtime behavior;
- generated code;
- CI/CD;
- registry;
- catalog;
- observability;
- operating model;
- incident learning.
They build systems where correct behavior is easier than incorrect behavior.
22. 20-Hour Deliberate Practice Plan
Based on Kaufman-style rapid skill acquisition:
Hours 1-3 — Read and Model
- review this series;
- draw API/event/schema taxonomy;
- model one domain’s contracts.
Hours 4-6 — Build Contract Repo
- create OpenAPI;
- create AsyncAPI;
- create Avro/Protobuf/JSON Schema;
- create Kafka topic metadata;
- add examples.
Hours 7-10 — Build Diff MVP
- parse artifacts;
- normalize;
- implement 10 diff rules;
- generate report.
Hours 11-13 — Add Policy
- write policy YAML;
- enforce CDR/migration requirements;
- add risk classification.
Hours 14-16 — Add Catalog
- build catalog model;
- expose REST endpoints;
- register consumers;
- show impact.
Hours 17-18 — Add Runtime Signals
- ingest violations;
- show dashboard data;
- add metrics/logging design.
Hours 19-20 — Simulate Incidents
- Avro field without default;
- Protobuf tag reuse;
- Kafka key change;
- new enum breaks consumer;
- deprecated event still used.
Write postmortem and update rules.
23. Final Capstone Deliverables
Produce:
- architecture diagram;
- contract repo fixture;
- Java modules;
- CLI;
- REST API;
- diff report examples;
- policy YAML;
- catalog sample data;
- runtime violation ingestion;
- test suite;
- runbook;
- README;
- portfolio write-up.
README sections:
# ContractHub
## Problem
## Architecture
## Supported Artifacts
## Diff and Compatibility Rules
## Policy-as-Code
## Catalog
## Runtime Enforcement Signals
## Demo Scenarios
## How to Run
## Design Trade-offs
## Future Work
24. Future Enhancements
- real schema registry adapters;
- GitHub PR bot;
- Backstage plugin;
- OpenTelemetry integration;
- Kafka Admin drift detector;
- graph lineage store;
- SDK compatibility checker;
- AI-assisted semantic change review;
- consumer field-usage analysis;
- automated migration guide generation;
- contract incident correlation;
- policy simulation before rollout.
25. Final Self-Assessment
You are ready if you can answer:
- Is this event really a fact?
- What compatibility direction matters?
- What breaks old consumers?
- Can new consumers replay old data?
- What is the Kafka key and why?
- What happens on duplicate delivery?
- What schema version is in production?
- Who owns this contract?
- Is this field PII?
- What is the deprecation plan?
- What runtime metric detects violation?
- What diff rule would catch this next time?
- What is safe to automate?
- What needs human semantic review?
- What is the migration path?
If yes, you have crossed from framework user to contract platform engineer.
26. Series Closure
This series covered:
- Kaufman skill map;
- contract taxonomy;
- invariants;
- source-of-truth strategy;
- OpenAPI;
- HTTP semantics;
- request/response design;
- error contracts;
- API versioning;
- OpenAPI in Java;
- API client engineering;
- API contract testing;
- event mental model;
- event envelope;
- AsyncAPI;
- Kafka contracts;
- Avro;
- Protobuf/gRPC;
- JSON Schema;
- event versioning;
- event contract testing;
- schema registry architecture;
- compatibility governance;
- schema lifecycle;
- review playbook;
- governance automation;
- contract diff;
- catalog;
- multi-team operating model;
- runtime enforcement;
- observability and incident response;
- capstone platform.
27. Final Heuristics
- Contracts are promises under change.
- Schema is not the whole contract.
- Compatibility is directional, temporal, semantic, operational, and social.
- Events are facts declared by authorities.
- Kafka key is contract.
- Generated Java code is consumer surface.
- Registry is governance infrastructure.
- Catalog is discovery plus impact analysis.
- Diff engine turns change into risk.
- Policy-as-code scales governance.
- Runtime enforcement catches reality drift.
- Observability makes contract quality operational.
- Deprecation without telemetry is hope.
- Incidents should become rules, tests, and runbooks.
- Top engineers build systems where safe evolution is easy and unsafe change is visible.
Final Summary
The final goal is not to memorize every tool. The goal is to develop contract judgment:
- know what promise is being made;
- know who relies on it;
- know how it evolves;
- know how it fails;
- know how to detect failure;
- know how to recover;
- know how to improve the system after learning.
That is the difference between writing APIs/events and engineering an enterprise contract platform.
Status seri: selesai. Ini adalah Part 032 dari 32.
You just completed lesson 32 in final stretch. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.
Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.