Interfaces & APIs
Contracts between humans and systems
What this chapter is
This chapter is not about REST. It is not about GraphQL. It is not about HTTP verbs, schemas, or tooling.
This chapter is about commitment.
An interface is the moment a system stops being private.
The core truth
An interface is a promise about behavior.
Once exposed, it will be:
- depended on
- worked around
- relied upon in unintended ways
You can change implementation freely. You cannot change promises cheaply.
🧠 Mental Model APIs outlive the intent of their creators.
Interfaces exist to protect both sides
A good interface protects:
- consumers from internal churn
- providers from consumer misuse
A bad interface:
- leaks internals
- invites coupling
- creates dependency traps
🧠 Architect's Note An interface should make the right thing easy and the wrong thing hard.
Stability beats expressiveness
The temptation is to expose everything.
Expressive APIs feel powerful early. They feel dangerous later.
Stable APIs:
- do less
- change rarely
- force discipline
🧠 Perspective An API that rarely changes is more valuable than one that can do everything.
Shape matters more than technology
Whether an interface is:
- a function
- a module
- a service
- a message
…the same rules apply.
Good interfaces:
- have clear inputs
- have clear outputs
- have clear failure modes
- hide internal decisions
Technology is incidental. Shape is essential.
Leaky abstractions hurt twice
When an interface leaks internal details:
- consumers depend on them
- providers become trapped by them
This creates:
- fragile integrations
- coordination overhead
- fear of change
🧠 Mental Model If consumers know how it works, you've already lost freedom.
Versioning is a cost, not a solution
Versioning feels like safety.
In reality, it:
- multiplies surface area
- splits attention
- prolongs bad decisions
Versioning should be:
- rare
- deliberate
- accompanied by deprecation
🧠 Architect's Note The best versioning strategy is needing it as little as possible.
Error behavior is part of the interface
An interface is incomplete without:
- defined failure modes
- consistent error signaling
- clear recovery expectations
Silence is not stability. Ambiguity is not flexibility.
🧠 Perspective Consumers will build logic around how you fail.
Interfaces create political boundaries
APIs exist between:
- teams
- organizations
- vendors
- timeframes
They are social contracts as much as technical ones.
Breaking an interface:
- costs trust
- costs coordination
- costs velocity
🧠 Mental Model Technical breakage becomes organizational friction.
Narrow interfaces scale better
Wide interfaces invite misuse. Narrow interfaces constrain behavior.
A narrow interface:
- limits dependency
- clarifies intent
- reduces coupling
🧠 Architect's Note You can always add later. Removing is painful.
Documentation is not decoration
Documentation explains:
- what is promised
- what is not
- what must not be assumed
Undocumented behavior becomes folklore. Folklore becomes dependency.
Interfaces and time
Interfaces must survive:
- new features
- new teams
- new requirements
- new scale
If an interface requires constant explanation, it is already failing.
Minimal practice (still no code)
Problem: "You expose a service that creates and updates user data."
Ask:
- What must always be true?
- What must never be allowed?
- What errors are expected?
- What assumptions should consumers not make?
If the answers are fuzzy, the interface is unsafe.
What beginners gain here
- Respect for contracts
- Less accidental coupling
- Cleaner boundaries
What experienced developers recognize
- Why integrations rot
- Why changes are risky
- Why APIs feel constraining over time
Promises were made too freely.
What this chapter deliberately avoids
- Protocol debates
- Tool comparisons
- Framework opinions
- Implementation mechanics
Those are downstream.
Closing
Interfaces are promises that bind the future.
Make them:
- small
- boring
- stable
- explicit
A system with good interfaces can evolve calmly. A system with bad ones lives in negotiation.