Start HereOrdered learning track

Contract Taxonomy

Learn Java API Contract Engineering, Event Contract Engineering & Schema Governance - Part 002

Taxonomy kontrak untuk HTTP API, RPC, event, command, query, webhook, batch, file, stream, schema, SDK, dan platform interface di enterprise Java systems.

30 min read5929 words
PrevNext
Lesson 0232 lesson track0106 Start Here
#java#api-contract#event-contract#schema-governance+3 more

Part 002 — Contract Taxonomy: HTTP APIs, Events, Schemas, Commands, Queries, and Platform Contracts

1. Tujuan Part Ini

Part 001 membangun mental model: contract sebagai boundary, promise, compatibility surface, dan governance artifact.

Part 002 menjawab pertanyaan berikut:

“Jenis contract apa yang sedang saya desain, dan apa konsekuensi engineering dari pilihan itu?”

Ini penting karena banyak incident contract terjadi bukan karena engineer tidak tahu syntax OpenAPI/AsyncAPI/Avro/Protobuf, tetapi karena salah mengklasifikasikan interaksi.

Contoh kesalahan taxonomy:

  • Event dipakai sebagai command.
  • API query dipakai sebagai workflow transition.
  • Webhook dianggap sama dengan internal event.
  • File exchange dianggap “hanya CSV”, padahal menjadi contract regulatory.
  • SDK dianggap helper, padahal menjadi compatibility surface.
  • Topic Kafka dianggap implementation detail, padahal consumer bergantung pada key, ordering, dan retention.
  • Schema registry dianggap cukup, padahal event semantics tidak tertulis.

Setelah part ini, kamu harus bisa:

  1. Mengklasifikasikan contract berdasarkan interaction model.
  2. Membedakan HTTP API, RPC, event, command, query, webhook, batch, file, stream, SDK, dan platform contract.
  3. Menjelaskan contract surface untuk setiap jenis.
  4. Menentukan compatibility risk per jenis contract.
  5. Memilih artifact yang tepat: OpenAPI, AsyncAPI, Avro, Protobuf, JSON Schema, IDL, ADR/CDR, catalog metadata, atau test contract.
  6. Membuat contract profile card untuk review enterprise.

2. Why Taxonomy Matters

Tanpa taxonomy, semua interface terlihat seperti “data lewat dari A ke B”. Itu terlalu dangkal.

Interface punya sifat berbeda:

InteraksiPertanyaan utama
HTTP APIApa yang diminta consumer dan apa response-nya sekarang?
Query APIBagaimana consumer membaca state tanpa mengubah state?
Command APIBagaimana consumer meminta perubahan state?
EventFakta bisnis apa yang sudah terjadi?
NotificationPihak lain perlu tahu apa, tanpa menjadi source of truth?
WebhookBagaimana external provider memanggil kita secara async-ish?
StreamApa sequence data yang terus mengalir?
Batch/FileSnapshot atau exchange periodik apa yang diproses?
SDKAbstraksi client apa yang menjadi public surface?
Platform contractInterface apa yang disediakan platform untuk teams?

Jika taxonomy salah, contract salah.


3. Contract Taxonomy Map

Diagram ini bukan sekadar daftar. Ia menunjukkan bahwa contract bisa berada di banyak layer.

Satu capability enterprise biasanya punya beberapa contract sekaligus.

Contoh capability Customer Onboarding:

POST /customers                         -> HTTP command API contract
GET /customers/{id}                     -> HTTP query API contract
CustomerRegistered                      -> domain event contract
CustomerKycApproved                     -> domain event contract
customer-events Kafka topic             -> topic operational contract
customer.v1.CustomerRegistered.avsc     -> Avro schema contract
customer-api Java client                -> SDK contract
Customer API catalog entry              -> discovery/governance contract
PII classification metadata             -> data governance contract

4. Taxonomy Dimension, Bukan Hanya Label

Jangan hanya bertanya “ini API atau event?” Tanyakan dimensi berikut.

4.1 Coupling Dimension

DimensionTightLoose
Temporal couplingConsumer menunggu response langsungConsumer tidak harus online saat event terjadi
Schema couplingConsumer compile terhadap generated classConsumer tolerant terhadap unknown fields
Semantic couplingConsumer bergantung pada detail domain spesifikConsumer hanya butuh fact umum
Operational couplingConsumer bergantung pada timeout/rate limit/orderConsumer bisa retry/replay/degrade
Release couplingProvider dan consumer deploy bersamaProvider dan consumer deploy independen

Contract engineering bertujuan mengelola coupling, bukan pura-pura semua loose-coupled.


4.2 Time Dimension

Time propertyMeaning
Request timeSaat consumer meminta sesuatu
Response timeSaat provider menjawab
Occurred timeSaat fakta bisnis terjadi
Effective timeSaat perubahan mulai berlaku
Published timeSaat event keluar
Processing timeSaat consumer memproses
Reporting periodPeriode data file/report
Retention windowBerapa lama data/event tersedia

Banyak contract buruk karena timestamp tidak punya semantic jelas.

Contoh buruk:

{
  "date": "2026-06-29"
}

Pertanyaan:

  • Date apa?
  • Created date?
  • Effective date?
  • Settlement date?
  • Business date?
  • Local timezone atau UTC?
  • Apakah inclusive/exclusive?

4.3 Authority Dimension

Contract typeSiapa authority?
Command APIProvider yang mengubah state
Query APIProvider sebagai source of truth atau read model
Domain eventProducer domain yang mengalami fakta
Integration eventIntegration layer atau anti-corruption layer
WebhookExternal system
File reportReport producer berdasarkan cut-off tertentu
CDC eventDatabase/source log, bukan necessarily domain semantic
SDKLibrary owner, tetapi behavior tetap mengikuti remote provider

Authority penting karena menentukan siapa yang boleh mengubah meaning.


4.4 Audience Dimension

AudienceGovernance expectation
Same-team internalLightweight, fast, but still testable
Cross-team internalOwnership, compatibility, review, catalog
Platform-wideStrict compatibility, strong docs, support model
Partner/externalFormal lifecycle, versioning, deprecation, SLA
Public APILong-term stability, security, abuse protection, docs quality
Regulatory/auditEvidence, traceability, controlled change, retention

Semakin jauh audience dari provider, semakin konservatif contract evolution harus dilakukan.


4.5 State Semantics Dimension

InteractionState meaning
CommandRequest to change state
QueryRead state
EventState already changed or fact occurred
NotificationSomething worth knowing, not necessarily source of truth
SnapshotState at a point in time
CDCLow-level data mutation
ReportDerived state for period/purpose

Kesalahan umum: event yang sebenarnya command.

Bad:

CreateInvoiceEvent

Jika maksudnya “please create invoice”, itu command.

Better:

CreateInvoiceCommand
InvoiceCreated

5. HTTP API Contract

HTTP API contract adalah contract untuk interaksi request-response melalui HTTP.

OpenAPI adalah artifact utama untuk mendeskripsikan HTTP API secara machine-readable.

5.1 Contract Surface

SurfaceContoh
Path/customers/{customerId}
MethodGET, POST, PUT, PATCH, DELETE
Path parametercustomerId
Query parameterpage, size, sort, status
HeadersAuthorization, Idempotency-Key, If-Match, X-Correlation-Id
Request bodyDTO input
Response bodyDTO output
Status code200, 201, 400, 404, 409, 422, 429, 500
Error modelerrorCode, message, details, retryable
Security schemeOAuth2, mTLS, API key
Rate limitQuota, burst, retry-after
CachingETag, Cache-Control
IdempotencyIdempotency key behavior

5.2 When to Use

Gunakan HTTP API ketika:

  • Consumer butuh request-response langsung.
  • Consumer perlu query state sekarang.
  • Consumer perlu command dengan immediate acknowledgement.
  • Human/developer usability penting.
  • API perlu mudah diakses lintas bahasa/platform.

5.3 Contract Risk

Risiko utama:

  • Status code tidak konsisten.
  • Error model tidak stabil.
  • Required field berubah.
  • Null/absent tidak jelas.
  • Pagination berubah.
  • Idempotency diklaim tetapi tidak benar.
  • Authentication/authorization behavior tidak terdokumentasi.
  • Response generated dari entity internal.

5.4 Java Implication

Di Java, HTTP API contract sering terhubung dengan:

  • Spring MVC/WebFlux controller.
  • Jakarta REST resource.
  • DTO records/classes.
  • Bean Validation.
  • Jackson serialization.
  • OpenAPI generator/springdoc/swagger-core.
  • Generated Java clients.

Tetapi jangan menjadikan Java controller sebagai satu-satunya contract source tanpa drift detection.


6. Command API Contract

Command API adalah API yang meminta provider melakukan perubahan state.

Contoh:

POST /accounts/{accountId}/close
POST /payments
POST /customers/{customerId}/kyc-verifications

6.1 Command Contract Must Define

  • Preconditions.
  • Idempotency.
  • Authorization.
  • State transition semantics.
  • Validation errors.
  • Business rule errors.
  • Accepted vs completed semantics.
  • Synchronous vs asynchronous execution.
  • Retry safety.
  • Conflict handling.

6.2 Bad Command Contract

POST /accounts/updateStatus

Request:

{
  "status": "CLOSED"
}

Masalah:

  • Generic update.
  • Tidak jelas transition reason.
  • Tidak jelas precondition.
  • Tidak jelas idempotency.
  • Tidak jelas apakah close immediate atau pending.
  • Tidak jelas error jika account punya unsettled transaction.

6.3 Better Command Contract

POST /accounts/{accountId}/closure-requests
Idempotency-Key: 01JZ0W...

Request:

{
  "reasonCode": "CUSTOMER_REQUEST",
  "requestedBy": "customer-service-agent",
  "requestedAt": "2026-06-29T10:00:00Z"
}

Response:

{
  "closureRequestId": "CLR-123",
  "accountId": "ACC-123",
  "status": "PENDING_SETTLEMENT",
  "nextReviewAt": "2026-06-30T00:00:00Z"
}

Contract improvement:

  • Command has business identity.
  • Request is idempotent.
  • State transition is explicit.
  • Async completion can be represented later by event.

7. Query API Contract

Query API membaca state tanpa mengubah state.

Contoh:

GET /customers/{customerId}
GET /accounts?customerId=CUST-123&status=ACTIVE
GET /payments/{paymentId}

7.1 Query Contract Must Define

  • Read consistency expectation.
  • Pagination.
  • Filtering.
  • Sorting.
  • Field projection.
  • Caching.
  • Authorization filtering.
  • Not found vs hidden due to authorization.
  • Snapshot time.
  • Staleness tolerance.

7.2 Common Risk

Query API sering dianggap sederhana, padahal consumer bisa bergantung pada subtle behavior.

Contoh:

GET /accounts?customerId=CUST-123

Pertanyaan contract:

  • Apakah mengembalikan closed accounts?
  • Urutan default apa?
  • Apakah hasil eventually consistent?
  • Apakah paging stable saat data berubah?
  • Apakah unauthorized account disembunyikan atau return 403?
  • Apakah empty list berarti tidak ada account atau data belum indexed?

8. RPC/gRPC Contract

RPC contract mendefinisikan method/service interface, sering dengan IDL seperti Protocol Buffers.

Contoh proto:

service CustomerService {
  rpc GetCustomer(GetCustomerRequest) returns (CustomerResponse);
}

8.1 When to Use

Gunakan RPC/gRPC ketika:

  • Internal service-to-service latency penting.
  • Strong typing lintas bahasa diperlukan.
  • Streaming RPC dibutuhkan.
  • Contract-first IDL cocok dengan platform.
  • Consumer dan provider relatif controlled.

8.2 Contract Surface

SurfaceContoh
Service nameCustomerService
Method nameGetCustomer
Request messageGetCustomerRequest
Response messageCustomerResponse
Field numbersProtobuf tags
Error/statusgRPC status + details
DeadlineTimeout expectation
MetadataHeaders/trailers
Streaming modeunary, server streaming, client streaming, bidi

8.3 Risk

  • Field number reuse.
  • Required semantic hidden behind optional fields.
  • Enum evolution failure.
  • Error details not standardized.
  • Deadline/retry behavior not documented.
  • Generated client creates false sense of compatibility.

9. Event Contract

Event contract mendeskripsikan fakta yang sudah terjadi.

Contoh:

CustomerRegistered
CustomerKycApproved
AccountActivated
PaymentSettled
CaseEscalated

9.1 Event is a Fact

Event harus bernama past tense atau fact-like.

Good:

InvoiceCreated
PaymentSettled
CustomerRiskRatingChanged

Suspicious:

CreateInvoice
SettlePayment
UpdateCustomerRisk

Jika message meminta sesuatu terjadi, itu command, bukan event.

9.2 Event Contract Surface

SurfaceContoh
Event type/nameCustomerKycApproved
EnvelopeeventId, occurredAt, producer, correlationId
Payloadbusiness facts
SchemaAvro/Protobuf/JSON Schema
Topic/channelcustomer.lifecycle.events
KeycustomerId
Orderingper customer
Retention30 days, compacted, infinite archive
Replayallowed/not allowed, side-effect rules
Compatibilitybackward/full/transitive
ClassificationPII/confidential/public

9.3 Event Contract Risk

  • Event name vague.
  • Payload is database row.
  • Missing event identity.
  • Missing occurredAt.
  • Key does not match ordering assumption.
  • Consumer treats notification as source of truth.
  • Schema compatibility passes but semantic meaning changed.
  • Replay breaks consumers because event processing has side effects.

10. Domain Event vs Integration Event vs Data Event

Tidak semua event sama.

10.1 Domain Event

Domain event merepresentasikan fakta bermakna dalam domain.

AccountClosed
CustomerKycApproved
FraudCaseEscalated

Kualitas:

  • Business language.
  • Stable meaning.
  • Published by domain owner.
  • Useful for multiple consumers.
  • Should survive implementation change.

10.2 Integration Event

Integration event dirancang untuk kebutuhan integrasi tertentu.

CustomerProfileSyncedToCrm
NotificationDispatchRequested

Kualitas:

  • Often narrower.
  • May be tied to integration flow.
  • Still needs contract, but lifecycle may be shorter.

10.3 Data Change Event / CDC

CDC event merepresentasikan perubahan data low-level.

customers table row updated
accounts.balance changed

Kualitas:

  • Strongly tied to persistence model.
  • Useful for replication/analytics.
  • Dangerous if treated as domain event.
  • Schema evolution tied to database evolution.

10.4 Comparison

TypeSourceMeaningConsumer risk
Domain eventDomain serviceBusiness factSemantic break
Integration eventIntegration serviceFlow-specific signalFlow coupling
CDC eventDatabase/logData mutationPersistence leakage

11. Command Message Contract

Command message adalah asynchronous request to do something.

Contoh:

GenerateMonthlyStatementCommand
SendCustomerNotificationCommand
RecalculateRiskScoreCommand

11.1 Contract Surface

  • Command name.
  • Command ID.
  • Target handler.
  • Preconditions.
  • Idempotency key.
  • Deadline/expiry.
  • Retry policy.
  • Expected outcome event.
  • Failure event/error channel.

11.2 Difference from Event

CommandEvent
ImperativePast fact
Directed to handlerBroadcastable
Can be rejectedAlready happened
Needs idempotencyNeeds deduplication/replay semantics
Often has deadlineHas occurredAt/effectiveAt

11.3 Common Mistake

Bad:

CustomerCreatedEvent consumed by Account Service to create account automatically.

If account creation is mandatory and directed, model the dependency explicitly.

Better options:

  1. Orchestrated command: CreateAccountForCustomerCommand.
  2. Choreography with domain event: CustomerRegistered plus account service independently decides.
  3. Workflow engine: state transition with commands and events.

The right choice depends on coupling and business ownership.


12. Notification Contract

Notification is “something worth telling”, but not necessarily canonical fact.

Examples:

CustomerProfileUpdatedNotification
PasswordResetEmailRequested
MaintenanceWindowAnnouncement

12.1 Notification Characteristics

  • Often lossy-tolerant.
  • May not be replayable.
  • Often user/channel oriented.
  • May duplicate domain facts in simpler form.
  • Consumer should not always treat it as source of truth.

12.2 Risk

  • Consumer starts relying on notification as authoritative state.
  • Notification payload lacks enough context.
  • Delivery guarantee unclear.
  • Duplicate notification causes bad user experience.

12.3 Contract Rule

Always state:

Is this notification authoritative?
Can consumers derive state from it?
Should consumers call a query API to fetch current state?

13. Webhook Contract

Webhook is an HTTP callback where an external/internal provider sends event-like messages to a consumer endpoint.

Example:

POST /webhooks/payment-provider/events

13.1 Webhook Contract Surface

  • Endpoint path.
  • Authentication/signature verification.
  • Event type.
  • Payload schema.
  • Delivery retry policy.
  • Timeout expected by sender.
  • Acknowledgement semantics.
  • Idempotency/deduplication.
  • Event ordering.
  • Replay/manual resend.
  • Versioning.

13.2 Webhook is Not Just HTTP API

Webhook uses HTTP transport, but its semantics are asynchronous event delivery.

So it needs both:

  • HTTP contract: status code, authentication, request body.
  • Event contract: event type, event ID, occurredAt, deduplication, retry, ordering.

13.3 Common Risk

  • Returning 200 before durable persistence.
  • No signature validation.
  • No replay handling.
  • No idempotency.
  • Treating delivery order as guaranteed without provider promise.
  • Not storing raw payload for forensic analysis.

14. Stream Contract

Stream contract describes continuous flow of records.

Examples:

  • Kafka topic.
  • Kinesis stream.
  • WebSocket feed.
  • Server-sent events.
  • gRPC streaming.

14.1 Contract Surface

  • Stream/channel name.
  • Record schema.
  • Keying/partitioning.
  • Ordering guarantee.
  • Delivery guarantee.
  • Retention.
  • Replay.
  • Consumer offset semantics.
  • Backpressure behavior.
  • Rate/volume expectation.
  • Schema evolution.

14.2 Stream-Specific Risk

  • Volume increase breaks consumers.
  • Key change breaks ordering.
  • Retention change breaks recovery.
  • Compaction semantics misunderstood.
  • Consumer assumes exactly-once because producer says “no duplicates”.
  • Schema is valid but record order causes wrong aggregation.

15. Batch/File Contract

Batch/file contracts are often underestimated.

Examples:

  • Daily settlement CSV.
  • Monthly regulatory report XML.
  • Partner reconciliation file.
  • Bulk customer import.
  • Data warehouse export.

15.1 Contract Surface

SurfaceExample
File name patternsettlement_YYYYMMDD_seq.csv
FormatCSV, JSONL, XML, Parquet
EncodingUTF-8
Delimitercomma, pipe, tab
Headerrequired/optional
Schemacolumns/elements/types
Null representationempty, NULL, missing
Date/time formatISO date, local business date
Orderingsorted by accountId? none?
Completenessfull snapshot or delta
Cut-off timebusiness day close
Delivery mechanismSFTP, object storage, API download
Retry/replacementoverwrite, append, correction file
Reconciliationcontrol totals/checksum

15.2 Why File Contract is Critical

File contracts often carry:

  • Money movement.
  • Regulatory reporting.
  • Partner settlement.
  • Bulk migration.
  • Audit evidence.

A CSV column rename can be as breaking as API field removal.

15.3 File Contract Risk

  • Excel-style formatting corrupts identifiers.
  • Leading zero lost.
  • Local timezone ambiguity.
  • Null vs empty string unclear.
  • Partial file processed as complete.
  • Reprocessing creates duplicates.
  • Correction file semantics unclear.

16. Schema Contract

Schema contract describes data shape independent of one transport.

Common schema technologies:

  • JSON Schema.
  • Avro schema.
  • Protobuf .proto.
  • XML Schema.
  • Database schema.
  • Parquet schema.

16.1 Schema is Not Enough

Schema can say:

{
  "type": "string",
  "enum": ["ACTIVE", "SUSPENDED", "CLOSED"]
}

It does not necessarily say:

  • What ACTIVE means.
  • Whether ACTIVE allows transaction.
  • Whether SUSPENDED can become ACTIVE again.
  • Whether CLOSED is terminal.
  • Whether enum can grow.

Contract engineering wraps schema with semantic and lifecycle policy.

16.2 Schema Contract Surface

  • Name.
  • Namespace/package.
  • Field names/types.
  • Required/optional/default.
  • Nullability.
  • Enum values.
  • References/imports.
  • Logical types.
  • Compatibility mode.
  • Owner.
  • Version.
  • Examples.

17. SDK/Client Library Contract

SDK is often forgotten as a contract.

Example:

CustomerClient client = CustomerClient.builder()
    .baseUrl(baseUrl)
    .tokenProvider(tokenProvider)
    .build();

Customer customer = client.getCustomer("CUST-123");

17.1 SDK Contract Surface

  • Public classes/methods.
  • Method signatures.
  • Exception types.
  • Retry defaults.
  • Timeout defaults.
  • Serialization behavior.
  • Thread-safety.
  • Dependency versions.
  • Configuration properties.
  • Backward compatibility of public API.

17.2 Risk

  • Generated client changes method names.
  • Exception hierarchy changes.
  • Retry policy changes silently.
  • Timeout default changes.
  • SDK exposes remote enum directly and breaks on new enum values.
  • SDK version not aligned with API version.

17.3 Rule

If consumers compile against it, it is a contract.


18. Platform Contract

Platform contract adalah interface yang platform team berikan ke application teams.

Examples:

  • How to provision Kafka topics.
  • How to register schema.
  • How to define API gateway route.
  • How to publish service metadata.
  • How to emit standard telemetry.
  • How to define deployment manifest.
  • How to request secrets.
  • How to configure rate limit.

18.1 Platform Contract Surface

  • YAML/JSON manifest schema.
  • CLI command interface.
  • Terraform module variables.
  • Helm chart values.
  • Annotation format.
  • Required metadata.
  • Policy constraints.
  • Lifecycle state.
  • Error messages.

18.2 Risk

  • Platform changes break all teams.
  • Manifest schema changes without migration.
  • Policy error messages unclear.
  • Teams bypass platform because contract is hard to use.
  • Contract exists but no compatibility guarantee.

18.3 Good Platform Contract Example

apiVersion: platform.example.com/v1
kind: KafkaTopic
metadata:
  name: customer.lifecycle.events
  owner: team-customer-platform
spec:
  partitions: 12
  retentionDays: 30
  cleanupPolicy: delete
  keyStrategy: customerId
  dataClassification: confidential
  schemaCompatibility: BACKWARD_TRANSITIVE

This is a contract between application team and platform.


19. Catalog Contract

Catalog entry is a governance/discovery contract.

It tells humans and tools:

  • What exists.
  • Who owns it.
  • How to consume it.
  • What lifecycle state it has.
  • What classification it has.
  • What dependencies exist.

19.1 Catalog Metadata

name: customer-api
kind: http-api
owner: team-customer-platform
domain: customer-onboarding
lifecycle: active
audience: internal-cross-team
contractLocation: contracts/openapi/customer-api.yaml
runtimeService: customer-service
dataClassification: confidential
supportChannel: '#team-customer-platform'
deprecation: null

19.2 Risk

  • Catalog stale.
  • Owner invalid.
  • Contract link broken.
  • Consumer list incomplete.
  • Classification missing.
  • Deprecated API still shown as preferred.

Catalog quality is part of contract governance.


20. Contract Artifact Selection

Choose artifact based on contract type.

Contract typePrimary artifactSupporting artifact
HTTP APIOpenAPIExamples, contract tests, ADR/CDR
gRPC/RPCProtobuf IDLBuf rules, generated clients, compatibility tests
Event APIAsyncAPISchema, examples, topic contract
Kafka event schemaAvro/Protobuf/JSON SchemaSchema registry metadata, AsyncAPI
WebhookOpenAPI + event schemaSignature docs, retry policy
Batch/fileSchema/spec docControl totals, sample files, reconciliation tests
SDKJava API surfaceSemVer policy, binary compatibility checks
Platform manifestJSON Schema/OpenAPI-like schemaPolicy-as-code, examples
Catalog entryYAML/JSON metadataOwnership validation, scorecard

Do not force every problem into OpenAPI.


21. Interaction Pattern Decision Tree

This tree is simplified. Real systems combine patterns.

Example:

  • API command accepts request.
  • Domain service changes state.
  • Event is published.
  • Consumer updates read model.
  • Query API exposes read model.
  • Batch report reconciles end-of-day.

Each step has a different contract.


22. Contract Composition in Real Systems

22.1 Customer Onboarding Example

Contracts involved:

FlowContract
UI -> APIHTTP command API contract
API -> UIResponse/error contract
API -> BrokerEvent contract + schema + topic contract
Broker -> KYCConsumer event expectation
KYC -> BrokerEvent contract + schema compatibility
Account -> BrokerEvent contract
Broker -> ReportReplay/retention/classification contract

Satu business flow bisa punya 8+ contract surfaces.


23. Taxonomy Matrix

Gunakan matrix ini untuk review.

TypeCouplingSource of truthArtifactMain riskGovernance strength
Command APITemporal tightProvider domainOpenAPIDuplicate side effect, bad error semanticsMedium-high
Query APITemporal tightProvider/read modelOpenAPIStaleness, pagination, authorization ambiguityMedium
RPCTemporal tightIDL/providerProtobufField number reuse, deadline/retry ambiguityMedium
Domain eventTemporal looseProducer domainAsyncAPI + schemaSemantic break, replay breakHigh
Command messageTemporal looseCommand ownerAsyncAPI + schemaDuplicate execution, expiry ambiguityHigh
NotificationLooseProducer or channel ownerAsyncAPI/schemaTreated as authoritative when notMedium
WebhookMixedExternal senderOpenAPI/schemaSignature/retry/idempotency failureHigh
StreamLoose but continuousProducer/platformAsyncAPI/schema/topic specOrdering/key/retention breakHigh
File/batchLoose periodicFile producerFile spec/schemaCut-off/null/control total ambiguityHigh
SDKCompile-time tightLibrary ownerJava API + docsBinary/source incompatibilityMedium-high
Platform manifestOperational tightPlatform teamJSON Schema/policyPlatform-wide breakVery high

24. Contract Profile Card

Setiap contract sebaiknya bisa dijelaskan dengan profile card.

# Contract Profile

## Identity
Name:
Type:
Domain:
Owner:
Audience:
Lifecycle State:

## Interaction
Provider:
Consumers:
Transport:
Synchronous/Asynchronous:
Command/Query/Event/Notification/Batch:

## Artifacts
Primary Contract:
Schema:
Examples:
Tests:
Catalog Entry:

## Compatibility
Compatibility Policy:
Safe Changes:
Breaking Changes:
Deprecation Window:
Consumer Migration Strategy:

## Operational Semantics
Idempotency:
Retry:
Ordering:
Timeout/Deadline:
Retention:
Replay:
Failure Channel:

## Governance
Reviewers:
Approval Policy:
Data Classification:
Security Requirements:
Audit Requirements:

## Observability
Contract Validation Metrics:
Consumer Error Signals:
Drift Detection:

This card forces taxonomy clarity.


25. Examples of Misclassification

25.1 Event Misclassified as Command

Bad:

UserSignupEvent consumed by Email Service, which must send welcome email.

If the business requirement is “send email”, there are options:

  • UserSignedUp event + Email Service independently reacts.
  • SendWelcomeEmailCommand if directed execution is required.
  • Workflow orchestration if retry/compensation/visibility matters.

Question:

Is Email Service observing a fact or being instructed?

25.2 Query Misclassified as Command

Bad:

GET /accounts/{id}/activate

This violates method semantics. It changes state via GET.

Better:

POST /accounts/{id}/activation-requests

25.3 CDC Misclassified as Domain Event

Bad:

Customer table updated -> all consumers treat it as CustomerProfileChanged

Problem:

  • Table update may include technical changes.
  • Not every update is domain-relevant.
  • Multiple domain meanings collapsed into one event.
  • Database schema change becomes event contract change.

Better:

  • CDC for replication/analytics.
  • Domain event for business fact.

25.4 File Contract Treated as Implementation Detail

Bad:

Finance team changes column order because parser uses headers anyway.

But partner parser may depend on column position.

Contract must specify:

  • Header required?
  • Column order stable?
  • Unknown columns tolerated?
  • Missing columns allowed?
  • File replacement semantics?

26. Java Project Layout by Contract Type

A contract-aware Java repository can separate artifacts clearly.

customer-platform/
  contracts/
    openapi/
      customer-command-api.yaml
      customer-query-api.yaml
    asyncapi/
      customer-events.yaml
    avro/
      CustomerRegistered.avsc
      CustomerKycApproved.avsc
    proto/
      customer_service.proto
    json-schema/
      customer-platform-manifest.schema.json
    files/
      monthly-customer-report.md
      examples/
  contract-tests/
    provider/
    consumer/
    schema-compatibility/
    replay/
  services/
    customer-service/
    kyc-service/
    account-service/
  catalog/
    customer-api.yaml
    customer-events.yaml

26.1 Why Separate Contracts from Implementation

Benefits:

  • Contract review can happen without reading service code.
  • Diff is easier.
  • Ownership metadata is explicit.
  • CI gates can run fast.
  • Contract artifacts can be published.
  • Catalog can index them.

Risk:

  • Contract drift if implementation verification is weak.

Therefore, separation must be paired with tests/generation.


27. Taxonomy and Compatibility

Compatibility differs by type.

27.1 HTTP API Compatibility

Usually safe:

  • Add new endpoint.
  • Add optional response field.
  • Add optional request field with default behavior.
  • Add new error detail field while preserving errorCode.

Usually breaking:

  • Remove endpoint.
  • Remove/rename field.
  • Change field type.
  • Change requiredness.
  • Change status code for same business outcome.
  • Change idempotency behavior.

27.2 Event Compatibility

Usually safe:

  • Add optional field with default/tolerant consumer policy.
  • Add new event type to topic if consumers tolerate unknown event types.
  • Add metadata field in envelope if ignored by old consumers.

Usually breaking:

  • Remove field.
  • Change field type.
  • Change event key.
  • Change event type name.
  • Change ordering guarantee.
  • Change occurredAt meaning.
  • Change replay semantics.

27.3 File Compatibility

Usually safe:

  • Add trailing optional column if consumers tolerate unknown columns.
  • Add optional XML element if parser tolerates it.
  • Add new file type with distinct name pattern.

Usually breaking:

  • Reorder columns if position-based consumers exist.
  • Change delimiter.
  • Change date format.
  • Change null representation.
  • Remove control total.
  • Change file completeness semantics.

27.4 SDK Compatibility

Usually safe:

  • Add method.
  • Add overload carefully.
  • Add optional configuration.
  • Add subtype if callers don't exhaustively switch.

Usually breaking:

  • Remove/rename public method.
  • Change method signature.
  • Change exception type.
  • Change default timeout/retry unexpectedly.
  • Upgrade dependency causing conflict.

28. Taxonomy and Ownership

Ownership must match semantic authority.

ContractOwner should be
Customer domain eventCustomer domain team
Kafka topic policyPlatform streaming team + domain owner
OpenAPI for customer APICustomer API provider team
Partner webhookIntegration/partner team
Regulatory report fileReporting domain owner + compliance reviewer
Platform manifestPlatform team
SDKAPI provider or developer experience team

Bad ownership:

Platform team owns all event schemas.

Platform team can own schema registry and policy. But domain event semantic must be owned by domain team.


29. Taxonomy and Governance Intensity

Not all contracts need equal process.

Interpretation:

  • High impact + high change frequency needs automation, not manual bottleneck.
  • High impact + low change frequency can tolerate stricter review.
  • Low impact + high frequency needs golden path and lightweight checks.
  • Low impact + low frequency should not be over-governed.

30. Boundary Between Contract and Implementation

A contract should not expose implementation details unless the implementation detail is intentionally part of the promise.

30.1 Bad Implementation Leakage

{
  "dbShard": "shard-7",
  "hibernateVersion": 3,
  "internalStatusFlag": "A1",
  "legacyCustomerPk": 982341
}

30.2 Legitimate Operational Contract

Some operational details are valid contract if consumer needs them.

Example event:

{
  "partitionKey": "CUST-123",
  "sequenceNumber": 89123
}

This can be legitimate if ordering/replay semantics require it.

Rule:

Expose operational detail only when it is stable, documented, and intentionally supported.

31. Semantic Contract Types

Beyond transport, contracts also differ by semantic role.

31.1 Entity Contract

Represents a business entity.

{
  "customerId": "CUST-123",
  "name": "...",
  "status": "ACTIVE"
}

Risk:

  • Becomes too large.
  • Consumers depend on every field.
  • Entity shape follows database.

31.2 State Transition Contract

Represents state movement.

{
  "caseId": "CASE-123",
  "fromState": "UNDER_REVIEW",
  "toState": "ESCALATED",
  "reasonCode": "HIGH_RISK"
}

Risk:

  • State machine semantics hidden.
  • Illegal transition not documented.
  • Reason code uncontrolled.

31.3 Decision Contract

Represents decision outcome.

{
  "decisionId": "DEC-123",
  "subjectId": "CUST-123",
  "outcome": "APPROVED",
  "policyVersion": "2026.06",
  "reasons": ["KYC_CLEAR"]
}

Risk:

  • Missing policy version.
  • Reasons not stable.
  • Explainability/audit weak.

31.4 Measurement Contract

Represents measured value.

{
  "metric": "risk_score",
  "value": 72,
  "scale": "0-100",
  "measuredAt": "2026-06-29T10:00:00Z"
}

Risk:

  • Unit/scale omitted.
  • Model version omitted.
  • Measurement time ambiguous.

31.5 Eligibility Contract

Represents allowed/not allowed decision.

{
  "eligible": false,
  "reasons": ["KYC_PENDING", "SANCTIONS_REVIEW"]
}

Risk:

  • Boolean hides nuance.
  • Reason taxonomy unstable.
  • Consumer treats current eligibility as future guarantee.

32. Contract Type Smells

Use these smells to detect wrong taxonomy.

SmellPossible issue
Event name starts with imperative verbIt may be a command
GET changes stateQuery/command confusion
Event payload mirrors DB tableCDC mistaken for domain event
Field named status has 12 unrelated valuesMultiple state dimensions collapsed
Webhook handler has side effects before persistenceRetry/idempotency risk
SDK catches all errors and returns nullError contract destroyed
File has no control totalsReconciliation risk
API returns 200 for business failureError semantics ambiguity
Enum has OTHER but no handling rulesSemantic escape hatch without governance
Topic name includes service implementationCoupling to producer internals

33. Contract Taxonomy Review Checklist

33.1 Identity

  • What is the contract name?
  • What type is it?
  • Who owns it?
  • Who consumes it?
  • Is the audience internal, external, partner, platform, or regulatory?

33.2 Interaction

  • Is it synchronous or asynchronous?
  • Is it command, query, event, notification, stream, file, or SDK?
  • Is the provider authoritative?
  • Does the consumer expect immediate response?
  • Does the interaction change state?

33.3 Artifact

  • Is OpenAPI appropriate?
  • Is AsyncAPI appropriate?
  • Is Avro/Protobuf/JSON Schema appropriate?
  • Is additional markdown/ADR/CDR needed for semantics?
  • Are examples included?

33.4 Compatibility

  • What changes are safe?
  • What changes are breaking?
  • What changes are semantically dangerous?
  • Is there a compatibility gate?
  • Is there a migration/deprecation path?

33.5 Operational Semantics

  • Retry behavior known?
  • Idempotency known?
  • Timeout/deadline known?
  • Ordering known?
  • Replay known?
  • Retention known?
  • Failure channel known?

34. Practical Classification Exercise

Classify each interaction.

Case 1

POST /payments

With Idempotency-Key, creates payment instruction.

Classification:

HTTP Command API Contract

Must define:

  • Idempotency.
  • Duplicate handling.
  • Accepted vs settled.
  • Error code taxonomy.
  • Payment state transition.

Case 2

PaymentSettled

Published after clearing/settlement completed.

Classification:

Domain Event Contract

Must define:

  • Settlement meaning.
  • OccurredAt/effectiveAt.
  • Payment ID.
  • Amount/currency precision.
  • Ordering per payment/account.
  • Replay safety.

Case 3

payments table updated CDC

Classification:

CDC/Data Change Event Contract

Must define:

  • Table schema.
  • Operation type.
  • Before/after image.
  • Transaction ordering.
  • Database schema compatibility.
  • Not necessarily domain meaning.

Case 4

POST /webhooks/stripe/events

Classification:

Webhook Contract

Must define:

  • Signature verification.
  • Event type registry.
  • Idempotency.
  • Retry acknowledgement.
  • Raw payload storage.

Case 5

monthly_regulatory_case_report_202606.csv

Classification:

Batch/File Regulatory Contract

Must define:

  • Reporting period.
  • Cut-off.
  • Schema.
  • Control totals.
  • Correction semantics.
  • Retention/audit.

35. Taxonomy-Driven Design Workflow

Use this workflow before writing any spec.


36. Enterprise Example: Enforcement Case Management

Karena banyak enterprise/regulatory systems punya lifecycle kompleks, lihat contoh Enforcement Case.

36.1 Candidate Interactions

Business needCorrect contract type
Create a caseCommand API
Read case detailsQuery API
Case assigned to investigatorDomain event
Request external agency reviewCommand message or partner API
Agency sends review completedWebhook/event
Daily case status exportBatch/file contract
Case state changes streamEvent stream
Investigator UI client librarySDK/client contract
Define case workflow manifestPlatform/workflow contract

36.2 Why This Matters

If CaseEscalated event is used to command another team to start investigation, the architecture hides obligation.

Better:

  • CaseEscalated states fact.
  • StartInvestigationCommand requests action.
  • InvestigationStarted confirms action happened.

This separation improves auditability.

In some systems, emitting both event and command may be overkill. But for regulatory lifecycle with accountability, the distinction is valuable.


37. Contract Taxonomy in Java Architecture

37.1 Package Boundaries

A contract-aware Java service should avoid mixing internal models and external contracts.

com.example.customer
  domain/
    Customer.java
    CustomerStatus.java
  application/
    RegisterCustomerUseCase.java
  api/
    http/
      CustomerController.java
      dto/
        RegisterCustomerRequest.java
        CustomerResponse.java
    events/
      CustomerRegisteredEvent.java
  infrastructure/
    persistence/
      CustomerEntity.java
    messaging/
      CustomerEventPublisher.java

Rule:

Domain model is not automatically API contract.
Persistence entity is not event contract.
Generated schema class is not automatically business model.

37.2 Boundary Mapping

Mapping is not busywork. Mapping is contract protection.

Each mapping is a place to enforce semantic boundary.


38. When One Contract Should Become Multiple Contracts

A common enterprise smell: one contract tries to serve every consumer.

38.1 Example Bad Unified Response

{
  "customerId": "CUST-123",
  "name": "...",
  "kycStatus": "APPROVED",
  "riskScore": 72,
  "accounts": [...],
  "latestTransactions": [...],
  "marketingPreferences": {...},
  "internalFlags": {...}
}

Problems:

  • Too many ownership domains.
  • Too much sensitive data.
  • Hard to evolve.
  • Consumer overfetching.
  • Authorization complex.
  • Cache invalidation unclear.

38.2 Better Split

  • Customer profile API.
  • Customer risk API.
  • Account summary API.
  • Marketing preference API.
  • Customer lifecycle events.
  • Risk decision events.

Contract taxonomy helps decide split by semantic ownership and consumer need.


39. When Multiple Contracts Should Become One

Opposite smell: too many tiny contracts causing fragmentation.

Bad:

CustomerNameChanged
CustomerPhoneChanged
CustomerEmailChanged
CustomerAddressChanged

Maybe okay if each has independent lifecycle. But if consumers always need complete profile changes, better:

CustomerProfileChanged

With changed fields:

{
  "customerId": "CUST-123",
  "changedFields": ["email", "phone"],
  "profileVersion": 17
}

Decision depends on:

  • Consumer use cases.
  • Frequency.
  • Semantic independence.
  • Replay needs.
  • Schema evolution risk.

40. Taxonomy and Data Classification

Contract type affects data policy.

Contract typeData classification risk
Public APIHigh external exposure
Partner APIContractual/legal exposure
Internal eventWide internal replication risk
CDCMay leak hidden sensitive fields
File exportBulk exfiltration risk
SDKLogs/errors may leak data
CatalogMetadata may reveal sensitive system info

Contract taxonomy must include classification.

Example metadata:

dataClassification: restricted
containsPII: true
piiFields:
  - customerName
  - nationalId
  - dateOfBirth
retentionPolicy: P7Y
allowedConsumers:
  - team-kyc
  - team-regulatory-reporting

41. Contract Taxonomy and Auditability

For audit-heavy systems, every contract type needs evidence.

ContractEvidence needed
Command APIWho requested, when, idempotency key, result
Query APIAccess log, authorization, data returned class
Domain eventEvent ID, occurredAt, producer, source transaction
Command messageCommand ID, handler, outcome event
File reportGeneration time, control totals, checksum, approval
Schema changeDiff, reviewer, compatibility result
WebhookSignature, raw payload, delivery attempts

Auditability is not added later. It is designed into contract.


42. Minimal Contract Metadata Standard

Enterprise teams should converge on minimal metadata.

x-contract:
  owner: team-customer-platform
  domain: customer-onboarding
  audience: internal-cross-team
  lifecycle: active
  compatibility: backward-compatible
  dataClassification: confidential
  containsPII: true
  supportChannel: '#team-customer-platform'
  deprecationPolicy: 180-days

For event:

x-event-contract:
  owner: team-customer-platform
  eventKind: domain-event
  authoritative: true
  orderingKey: customerId
  replayable: true
  retention: P30D
  compatibility: backward-transitive

This metadata can later drive linting, catalog, review routing, and CI gates.


43. Part 002 Exercises

Exercise 1 — Classify 10 Interfaces

List 10 interfaces from your current/past systems.

For each:

## Interface
Name:

## Classification
Type:
Synchronous/Asynchronous:
Command/Query/Event/Notification/File/SDK/Platform:

## Source of Truth

## Consumers

## Contract Artifact

## Main Compatibility Risk

## Main Governance Requirement

Exercise 2 — Find Misclassified Events

Search for event names that start with:

Create
Update
Delete
Send
Generate
Process
Run
Calculate

For each, ask:

  • Is this truly an event?
  • Is it a command?
  • Is it a notification?
  • Is the target handler implicit?
  • Is failure/retry behavior defined?

Exercise 3 — Contract Surface Expansion

Take one simple API:

GET /customers/{id}

Expand its contract surface:

  • Path.
  • Method.
  • Parameters.
  • Headers.
  • Response fields.
  • Error model.
  • Authorization.
  • Caching.
  • Staleness.
  • Rate limit.
  • Consumer assumptions.

Exercise 4 — File Contract Hardening

Take any CSV/report file. Define:

  • File name pattern.
  • Encoding.
  • Delimiter.
  • Column order.
  • Null representation.
  • Date/time format.
  • Control totals.
  • Correction semantics.
  • Partial failure handling.
  • Reprocessing idempotency.

44. Review Questions

  1. Apa perbedaan command API dan query API?
  2. Mengapa event harus dimodelkan sebagai fact?
  3. Kapan CDC event tidak boleh dianggap domain event?
  4. Mengapa webhook butuh HTTP semantics dan event semantics sekaligus?
  5. Apa contract surface dari SDK Java?
  6. Apa risiko menganggap file CSV sebagai implementation detail?
  7. Mengapa platform manifest adalah contract?
  8. Bagaimana taxonomy mempengaruhi compatibility policy?
  9. Bagaimana taxonomy mempengaruhi governance intensity?
  10. Mengapa semantic authority penting untuk ownership?

45. Ringkasan

Contract taxonomy membantu kita memilih model yang benar sebelum menulis spec.

Poin utama:

  1. Contract bukan hanya API. Contract bisa berupa event, schema, file, stream, SDK, catalog entry, atau platform manifest.
  2. Command, query, event, notification, CDC, dan file punya semantic berbeda.
  3. Salah taxonomy menghasilkan salah compatibility policy.
  4. Contract surface berbeda untuk setiap type.
  5. Ownership harus mengikuti semantic authority.
  6. Governance intensity harus mengikuti consumer impact dan change frequency.
  7. Java implementation harus menjaga boundary antara domain model, DTO, event payload, persistence entity, dan generated schema class.

Part berikutnya akan masuk ke Contract Invariants: hal-hal yang tidak boleh berubah sembarangan meskipun schema terlihat valid.


References

Lesson Recap

You just completed lesson 02 in start here. 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.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.