Section 4: Twenty Posts, One Round Trip - API Design (with Pushback)
Executive Summary: Section 3, Scale Estimation & Workload Analysis, put the read path at 350,000 page requests a second and the write path at about 1,200 posts a second. This section writes the contract both paths flow through: media on a pre-signed URL, a post created with an Idempotency-Key, idempotent follows, and one feed GET that returns 20 hydrated posts and an opaque cursor. We walk Dev's hike photo and Maya's 9:00:04 open across the wire, then defend five shapes under pushback: hydrated posts, a cursor, pull over a WebSocket, the idempotency key, and identity from the token.
The interviewer hands you the marker: "Show me the API." Before you write a path, say what decides the shape. Both customers from Section 1 are on phones. Dev publishes from a trail with one bar of signal. Maya opens the app on a bus. Every extra round trip costs real time on a mobile network, and every request can be retried by an app that never saw the response. So the contract has two rules: one round trip per screen, and every write safe to repeat.
The Whole Surface
| Purpose | Endpoint | Returns |
|---|---|---|
| Start a media upload | POST /v1/media/uploads {content_type, bytes} |
201 {media_id, upload_url}, a pre-signed URL |
| Create a post | POST /v1/posts + Idempotency-Key header, {media_ids, caption, visibility} |
201 {post_id, created_at} |
| Delete a post | DELETE /v1/posts/{post_id} |
204, author only |
| Follow | PUT /v1/me/following/{user_id} |
200 {state: "following" | "requested"} |
| Unfollow | DELETE /v1/me/following/{user_id} |
204 |
| Home feed | GET /v1/feed?limit=20&cursor=<opaque> |
200 {items, next_cursor, snapshot_expires_at} |
| Profile grid | GET /v1/users/{user_id}/posts?cursor=<opaque> |
200 {items, next_cursor} |
Every call carries a bearer token, and the caller's identity comes from it. That's why the paths say me. No endpoint takes "who am I" as a parameter.
Follow uses PUT and DELETE on purpose. The resource is the edge "Maya follows Dev", and putting it twice leaves the same state. A POST /follow that toggles would undo itself on a retry. A private account answers "requested" instead of "following", and no posts flow until the owner approves.
Delete marks the post deleted and returns 204. It doesn't touch the ~300 feeds that hold the post's ID; hydration drops it at read time (Section 7's deep dive).
Quick check before moving on:
Sign in to continue reading
The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.
Sign in to read the full lesson