API Design, Idempotency & Transactions
SECTION 1 — API DESIGN AS A LONG-TERM CONTRACT
At senior+ level, APIs are not implementation details.
They are:
-
contracts
-
promises
-
long-lived interfaces
-
externalized business rules
An API, once shipped, is almost impossible to take back.
Core Truth
APIs should change slower than internal code.
Elite backend engineers design APIs as if:
-
thousands of clients depend on them
-
some clients will never upgrade
-
clients will misuse them
Because that is reality.
SECTION 2 — THE API DESIGN HIERARCHY
Elite engineers design APIs in this order:
-
Domain language
-
Resources & boundaries
-
Operations
-
Validation rules
-
Error contracts
-
Versioning strategy
Average engineers start at step 4.
1️⃣ Domain-First Design
Before endpoints exist, define:
-
domain entities
-
invariants
-
transitions
-
forbidden states
Example:
“An application cannot be approved unless it is verified.”
This rule must live in one place — the backend.
2️⃣ Resource Boundaries
Good APIs expose nouns, not actions.
POST /applications
GET /applications/{id}
POST /applications/{id}/submit
POST /applications/{id}/approve
Why this matters:
-
boundaries become clear
-
permissions become enforceable
-
workflows become explicit
SECTION 3 — IDENTITY, AUTH & TRUST BOUNDARIES
Backend engineers must answer two questions perfectly:
-
Who is calling me?
-
What are they allowed to do?
Anything less is insecurity.
Authentication ≠ Authorization
Authentication:
“Who are you?”
Authorization:
“What are you allowed to do?”
Never mix them.
Elite Rule
Authorization must be enforced in backend business logic, not in the frontend.
Frontend can assist — backend must enforce.
SECTION 4 — IDEMPOTENCY (NON-NEGOTIABLE)
Idempotency is mandatory for real backend systems.
Reality of Distributed Systems:
-
requests are retried
-
users double-click
-
gateways time out
-
mobile networks drop
If your backend cannot handle duplicate requests → it is broken.
Idempotency Definition
Repeating the same operation produces the same result.
Where Idempotency Is Required
-
payments
-
bookings
-
submissions
-
approvals
-
mutations with side effects
Standard Pattern (Production-Grade)
Idempotency-Key: uuid
Backend flow:
-
Receive request
-
Check idempotency store
-
If exists → return stored response
-
Else:
-
execute operation
-
store result
-
return response
-
This must be atomic.
Elite Insight
Idempotency is not a “feature”.
It is a correctness guarantee.
SECTION 5 — TRANSACTIONS AS REALITY BOUNDARIES
Transactions define when the world changes.
Anything outside a transaction is uncertain.
What Transactions Guarantee
-
atomicity
-
consistency
-
isolation
-
durability
But only if used correctly.
Common Anti-Patterns
❌ Long transactions
❌ External calls inside transactions
❌ Multiple unrelated responsibilities
❌ Hidden transactions via ORM magic
Elite Transaction Rule
Transactions should be small, short, and purposeful.
Inside a transaction:
-
validate state
-
enforce invariants
-
mutate data
-
commit
Nothing else.
SECTION 6 — DATA MODELING FOR CORRECTNESS
Backend engineers model truth, not convenience.
Good Data Models:
-
encode invariants
-
prevent invalid states
-
make illegal actions impossible
-
simplify business logic
Example: Status Columns
Bad:
status = "approved"
Better:
status ENUM('draft','submitted','verified','approved','rejected')
Even better:
-
separate state table
-
transition history
-
audit logs
Elite Rule
If invalid state is possible in DB, it will occur eventually.
SECTION 7 — SCHEMA EVOLUTION & MIGRATIONS
Production schemas never stop evolving.
Elite engineers plan for:
-
backward compatibility
-
rolling deploys
-
partial upgrades
Migration Rules
-
Add before remove
-
Make new fields nullable
-
Backfill asynchronously
-
Deploy code that handles both versions
-
Remove old fields last
Violating these causes outages.
SECTION 8 — ERROR HANDLING AS PART OF DESIGN
Errors are not exceptions.
They are part of the contract.
Elite Error Design
-
structured
-
predictable
-
actionable
-
non-leaky
Example:
{
"error": {
"code": "INVALID_STATE",
"message": "Application must be verified before approval"
}
}
Never:
-
expose stack traces
-
expose DB errors
-
mix transport & business errors
SECTION 9 — TESTING FOR CORRECTNESS (NOT COVERAGE)
Elite backend tests focus on:
-
invariants
-
transitions
-
failure modes
-
retries
-
race conditions
Coverage is a side effect, not the goal.
Required Test Types
-
unit tests for domain logic
-
integration tests for workflows
-
idempotency tests
-
concurrency tests
SECTION 10 — BACKEND ENGINEER’S DAILY MINDSET
Top engineers ask:
-
What happens if this is retried?
-
What happens if this fails halfway?
-
What happens if two requests race?
-
What happens if the DB is slow?
-
What happens if state is stale?
If you don’t ask these, bugs will.
SECTION 11 — SIGNALS YOU’VE MASTERED THIS LAYER
You know you’re there when:
-
you naturally design idempotent APIs
-
you think in transactions & invariants
-
you trust backend logic over UI
-
you can reason about correctness under failure
-
you prevent bugs instead of fixing them