Contracts and Interfaces — How: The Method
The Contract Template
A well-defined contract has five components. Use this template every time:
CONTRACT: [Name]
ACCEPTS:
- [input 1]: [type/shape] — [constraints]
- [input 2]: [type/shape] — [constraints]
RETURNS:
- [output]: [type/shape] — [guarantees]
ERRORS:
- [condition] → [response]
- [condition] → [response]
SIDE EFFECTS:
- [what else occurs, if anything]
Designing Good Inputs
Be specific about shape
Not "a customer" — but "a customer ID (text, 8-12 alphanumeric characters)." Not "order data" — but "order containing: list of items (each with product_id and quantity), shipping address, and payment method."
Vague inputs create ambiguity. Ambiguity creates bugs.
Distinguish required from optional
Some inputs must always be present. Others have reasonable defaults. Make this explicit:
ACCEPTS:
- search_query: text — required, 1-200 characters
- page_number: number — optional, defaults to 1
- results_per_page: number — optional, defaults to 20, maximum 100
Define constraints
What's valid? What's invalid?
- "email: text — must contain exactly one @ symbol and at least one . after the @"
- "quantity: number — must be a positive integer, maximum 999"
- "date: text — must be in YYYY-MM-DD format, cannot be in the past"
Designing Good Outputs
Be explicit about guarantees
Don't just say "returns a list." Say:
- "Returns a list of orders, sorted by date descending"
- "Returns an empty list if no orders exist" (different from returning an error)
- "Each order contains: order_id, date, total, and status"
Define the shape
RETURNS:
- user:
- id: text
- name: text
- email: text
- created_date: text (YYYY-MM-DD format)
- is_active: yes/no
Handle empty results explicitly
What happens when there's nothing to return?
- Return an empty list?
- Return nothing at all?
- Return an error?
These are three different behaviors. The contract must specify which one.
Designing Good Error Cases
Errors are part of the contract, not an afterthought.
Be exhaustive
List every way the operation can fail:
ERRORS:
- Input validation:
- email is empty → error: "Email is required"
- email format is invalid → error: "Invalid email format"
- email already exists → error: "Email already registered"
- Business rules:
- account is suspended → error: "Account suspended"
- System failures:
- database unreachable → error: "Service temporarily unavailable"
Distinguish caller errors from system errors
Caller errors: "you sent me bad input" — expected, the caller should handle them System errors: "something is broken internally" — unexpected, needs investigation
Define recovery guidance
- "If 'rate limit exceeded,' wait 60 seconds and retry"
- "If 'session expired,' re-authenticate and retry"
- "If 'item out of stock,' do not retry — display message to user"
Documenting Side Effects
A side effect is anything the operation does besides returning a value:
PlaceOrderreturns the order ID, but also sends a confirmation emailDeleteAccountreturns success, but also erases all stored dataLoginreturns a session token, but also logs the event and updates the last-login timestamp
If a side effect is not documented, someone will depend on it unknowingly.
The Contract Review Checklist
When evaluating a contract, ask:
- Can a stranger implement this? Could someone who has never seen the system build a correct implementation from this contract alone?
- Are all inputs fully defined? Shape, constraints, required vs. optional?
- Are all outputs fully defined? Shape, guarantees, empty behavior?
- Is every error case listed? Input validation, business rules, system failures?
- Are side effects documented? Everything beyond returning the output?
- Is the contract implementation-free? Does it say what without saying how?
- Could this contract survive a rewrite? If internals were completely replaced, would it still make sense?
What to Look For in the Examples
The following pages show complete contract sets for three different systems. As you read:
- Notice the level of detail in inputs — every constraint, every edge case
- Notice how errors are categorized — caller errors vs. system errors
- Notice side effects you wouldn't have thought of — logging, notifications, state changes
- Notice how contracts chain together — the output of one becomes the input of the next
- Compare the same type of operation across different systems — a "create" operation in a library vs. a restaurant vs. a bank