Contracts and Data Workshop
Retrieval Prompts
- State the database-per-service rule in one sentence.
- Name three legitimate alternatives to a shared database.
- Name the three contract shapes and one discipline that applies to all of them.
- State the consumer-driven contract testing loop in order.
- Name three safe and three breaking changes for a sync API.
Compare and Distinguish
Separate these pairs clearly:
- API composition vs CQRS read model vs event-carried state transfer
- sync API contract vs event contract
- producer-owned contract vs consumer-owned contract
- backward compatibility vs forward compatibility
- tolerant reader vs strict reader
Common Mistake Check
For each statement, identify the error:
- "Different services use different schemas in the same database, so it is not a shared database."
- "We have OpenAPI specs so our contracts are enforced."
- "The provider writes the contract tests because they own the API."
- "Events don't need schemas because they are fire-and-forget."
- "We added a required field -- consumers will just start sending it on the next deploy."
Mini Application: End-to-End Contract
Using the decomposition from practice page 01 (or the e-commerce example), pick one cross-service interaction. For example: Orders publishes OrderConfirmed for Inventory and Fulfillment to consume.
Produce all of the following. Budget: 60 minutes.
1. Owned-Data Table
| Service | Database | Owned aggregates | Consumes (via events/sync) |
|---|
Fill at least 4 rows.
2. Sync API Contract (OpenAPI Fragment)
Write a minimal OpenAPI fragment for one endpoint used in the interaction. Include:
- one path with one method
- request parameters (path, query)
- two response codes (success + one failure)
- at least one reusable
components/schemasblock with 4+ fields
Example skeleton:
openapi: 3.0.3
info: { title: X API, version: "1.0.0" }
paths:
/orders/{id}:
get:
parameters: [ ... ]
responses:
"200": { content: { application/json: { schema: { $ref: ... } } } }
"404": { description: Not found }
components:
schemas:
Order: { type: object, required: [...], properties: { ... } }
3. Event Schema (JSON Schema)
Write a JSON Schema for the matching async event. Include:
event_id,event_version,occurred_at- domain payload with at least 4 fields
requiredlist- a nested object or array for a realistic domain shape
4. Compatibility Rules
List:
- three safe additions for each contract
- two breaking changes for each contract
- one expand-contract plan for renaming a field (phases: expand / migrate / contract)
5. Consumer-Driven Contract Test Specification
For one consumer (say, Inventory reading from Orders), specify:
- consumer and provider names
- provider state ("given order 123 is confirmed")
- request (method, path)
- expected response (status, representative body)
- the three expectations that, if broken on the provider, should fail this test
6. Cross-Service Data Pattern Choice
For three cross-service reads in your decomposition, classify each as:
- API composition
- CQRS projection
- Event-carried state transfer
Justify each choice in one sentence.
Evidence Check
This page is complete only if you can:
- show an OpenAPI fragment that would compile in a linter
- show a JSON Schema that validates at least one example event
- state a breaking-vs-safe classification from memory for 5 changes
- sketch a Pact-style consumer test without looking at the concept page
- reject any proposed design that has a shared OLTP table
If any of those are missing, redo the relevant section.