Design the contract before hiding it behind components#
An API is the boundary clients depend on. Resource names, validation, error behavior, and retry semantics should remain understandable even if the implementation moves from one service to many.
POST /urls
GET /urls/{id}
DELETE /urls/{id}Nouns identify resources; methods communicate the requested operation. Define input and output schemas, required fields, limits, and stable error shapes. Authorization belongs at or behind this boundary, but permission checks must still follow the resource.
Collections need deliberate behavior#
Filtering and sorting belong in an explicit contract such as GET /notifications?status=unread&sort=-created_at. Pagination needs its own stability decision, covered in the Pagination lesson. Version only when compatible evolution cannot carry the change; versioning does not excuse an unclear contract.
Asynchronous work changes acknowledgement#
Accept a video upload for processing
POST /video-uploads
202 Accepted
Location: /video-uploads/job_742The response means processing was accepted, not completed. The contract needs a job identifier and a way to observe progress or failure. Internal workers can change without changing that external meaning.
Exercise: basic chat APIs#
Design operations to create a conversation, send a message, and fetch history. Decide which identifiers the client provides and how a retry behaves.
Reveal one reasonable contract
POST /conversations
POST /conversations/{conversationId}/messages
GET /conversations/{conversationId}/messages?limit=50&before=<cursor>The send operation should define an idempotency mechanism; history needs stable ordering and pagination. Authorization must verify conversation membership on every resource operation.
- Putting verbs and implementation names into every path.
- Returning
200for every outcome and forcing clients to parse prose. - Leaking internal database schemas into a public contract.
- Adding API versions before defining compatibility policy.
Related practice problems
Use the manifest-backed prompts below to apply this lesson in a complete design.
- RFC 9110: HTTP SemanticsIETF / RFC Editor