Skip to main content
  1. System Design Components/

API Derivation Cheat Sheet

API Derivation Cheat Sheet #

Use this note as the bridge between:

  • functional requirements
  • entities
  • write shapes
  • HLD

The goal is not to design perfect REST. The goal is to make the system concrete and interview-friendly.


Why APIs matter #

APIs force you to answer:

  • who calls the system
  • what the main objects are
  • what the core write paths are
  • whether the path is sync or async
  • where idempotency matters
  • where pagination or conditional updates matter

So the delivery flow becomes:

  1. functional requirements
  2. NFRs
  3. entities
  4. APIs
  5. HLD
  6. deep dives

Mental model #

Derive APIs from paths.

  • path tells you the operation
  • entity tells you the resource
  • write shape tells you the endpoint style

Then add the few semantics that matter:

  • idempotency
  • pagination
  • conditional versioning
  • async job status
  • projection reads

Path -> API Shape #

1. Create Target #

Examples:

  • create post
  • create order
  • create profile
  • upload file metadata

Typical API:

  • POST /posts
  • POST /orders
  • POST /profiles

Mention when needed:

  • idempotency key if duplicate create is dangerous
  • request id if retry ambiguity matters

Good interview line:

This is a create target path, so I’d expose a POST on the primary resource and add an idempotency key if duplicate creation is harmful.


2. Overwrite Current Value #

Examples:

  • edit profile
  • rename file
  • update feature flag
  • update listing

Typical API:

  • PATCH /profiles/:id
  • PATCH /files/:id
  • PUT /flags/:id

Mention when needed:

  • version / etag / If-Match
  • partial vs full update

Good interview line:

This is an overwrite path, so I’d use PATCH or PUT with a version token to avoid lost updates.


3. State Transition #

Examples:

  • cancel booking
  • accept suggestion
  • revoke share
  • follow/unfollow
  • restore file

Typical API styles:

  • action-style:
    • POST /bookings/:id/cancel
    • POST /suggestions/:id/accept
  • relation-style:
    • PUT /follows/:target_user_id
    • DELETE /follows/:target_user_id

Mention when needed:

  • guarded transition from current state
  • idempotent retry behavior
  • expected no-op vs conflict

Good interview line:

This is a lifecycle transition, so I’d use either an action endpoint or relation add/remove endpoint, and I’d make the transition conditional on the current state.


4. Append Child Object #

Examples:

  • comment on post
  • reply to thread
  • leave review
  • append message

Typical API:

  • POST /posts/:id/comments
  • POST /comments/:id/replies
  • POST /businesses/:id/reviews

Mention when needed:

  • request id if duplicate append is harmful
  • cursor pagination for reads

Good interview line:

This is an append child path, so I’d model it as POST on the parent collection.


5. Read Source #

Examples:

  • view profile
  • view order status
  • view seat map
  • view current document

Typical API:

  • GET /profiles/:id
  • GET /orders/:id
  • GET /events/:id/seats
  • GET /documents/:id

Mention when needed:

  • strong vs bounded-stale source read
  • actor-specific authorization

Good interview line:

This is a source read path, so I’d expose a direct GET on the canonical resource.


6. Read Projection #

Examples:

  • search
  • feed
  • top K
  • recommendations
  • dashboards

Typical API:

  • GET /search?...
  • GET /feed/home
  • GET /hashtags/:tag/posts
  • GET /leaderboards/global
  • GET /recommendations

Mention when needed:

  • cursor pagination
  • freshness bounds
  • eventual consistency acceptable

Good interview line:

This is a projection read, so I’d expose it as a dedicated query endpoint and explicitly call out freshness and pagination.


7. Claim / Lease / Worker Path #

Examples:

  • worker claims job
  • scheduler creates due run
  • worker marks run success/failure

Typical API:

  • internal queue contract
  • POST /internal/jobs/claim
  • POST /internal/jobs/:id/complete
  • POST /internal/jobs/:id/fail

Mention when needed:

  • claim token / lease id
  • worker ownership
  • retry semantics

Good interview line:

This is an internal claim path, so I’d treat it as a worker API or queue contract rather than a public user API.


Archetype -> Typical APIs #

Current-Value Entity #

  • POST /resource
  • GET /resource/:id
  • PATCH /resource/:id

Examples:

  • profile
  • listing
  • document metadata

Relation / Edge #

  • PUT /follows/:target_id
  • DELETE /follows/:target_id
  • GET /users/:id/followers
  • GET /users/:id/following

Examples:

  • follows
  • likes
  • bookmarks
  • subscriptions

Append Child Object #

  • POST /posts/:id/comments
  • GET /posts/:id/comments?cursor=...

Examples:

  • comments
  • messages
  • reviews

Workflow / Lifecycle #

  • POST /orders
  • POST /orders/:id/cancel
  • GET /orders/:id

Examples:

  • orders
  • bookings
  • refunds

Inventory / Constrained Resource #

  • GET /events/:id/seats
  • POST /seat-holds
  • POST /bookings
  • POST /bookings/:id/cancel

Examples:

  • seats
  • rooms
  • stock
  • slots

Search / Projection #

  • GET /search
  • GET /feed/home
  • GET /leaderboards/global
  • GET /hashtags/trending

Control Plane #

  • POST /flags
  • PATCH /flags/:id
  • GET /flags/:id
  • POST /flags/:id/rollout

Examples:

  • feature flags
  • config
  • policy

The extra semantics to mention #

Do not over-design the API section. Usually mention only the semantic knobs that matter.

1. Idempotency #

Mention for:

  • payments
  • purchases
  • creates where duplicates hurt
  • retries on unstable networks

Example:

  • Idempotency-Key header on POST /bookings

2. Conditional update / versioning #

Mention for:

  • overwrites
  • guarded transitions
  • shared mutable state

Example:

  • If-Match: version
  • or request body field expected_version

3. Pagination #

Mention for:

  • lists
  • feeds
  • history
  • followers
  • comments
  • search results

Default:

  • cursor pagination, not offset, for large moving datasets

4. Async workflow status #

Mention for:

  • long-running jobs
  • uploads
  • indexing
  • batch processing
  • payout/refund workflows

Example:

  • POST /exports
  • GET /exports/:id

5. Projection freshness #

Mention for:

  • search
  • feed
  • leaderboard
  • trending

Example line:

This endpoint is served from a projection, so results may lag source truth by a few seconds.


Public API vs internal API #

Separate these clearly in interviews.

Public / product-facing #

Examples:

  • create post
  • follow user
  • search businesses
  • hold seat

Internal / system-facing #

Examples:

  • claim reminder job
  • complete campaign batch
  • push feed fanout task
  • projection updater writes

You usually do not need to expose internal APIs unless:

  • they are central to the design
  • they explain correctness
  • they explain async workflow boundaries

Example derivations #

Example 1: Follow system #

Paths:

  • follow user
  • unfollow user
  • view followers list
  • view follower count

Entities:

  • FollowRelation
  • FollowerCountView

APIs:

  • PUT /follows/:target_user_id
  • DELETE /follows/:target_user_id
  • GET /users/:id/followers?cursor=...
  • GET /users/:id/follower-count

What to mention:

  • follow/unfollow is guarded add/remove
  • followers list may come from source index
  • count comes from projection and may lag

Example 2: Ticketmaster #

Paths:

  • browse events
  • seat map
  • hold seat
  • buy seat

Entities:

  • Event
  • SeatInventory
  • SeatHold
  • Booking

APIs:

  • GET /events
  • GET /events/:id/seats
  • POST /seat-holds
  • POST /bookings

What to mention:

  • POST /seat-holds needs strong validation
  • POST /bookings should use idempotency key
  • seat map may be slightly stale, but hold/buy revalidates strongly

Example 3: Google Docs suggestions #

Paths:

  • edit document
  • create suggestion
  • accept suggestion
  • comment on range
  • view history

Entities:

  • Document
  • Suggestion
  • Comment
  • DocumentHistoryView

APIs:

  • PATCH /documents/:id
  • POST /documents/:id/suggestions
  • POST /suggestions/:id/accept
  • POST /documents/:id/comments
  • GET /documents/:id/history

What to mention:

  • edit and accept may require document version checks
  • history is a projection
  • comment is append child

What not to do #

  • do not invent dozens of endpoints
  • do not spend time on perfect REST purity
  • do not design every internal RPC unless it matters
  • do not skip pagination on large list endpoints
  • do not forget idempotency on dangerous create/commit paths

Interview one-liner #

I derive APIs directly from the critical paths: POST for create and append, PATCH/PUT for overwrite, action endpoints or guarded add/remove for lifecycle transitions, GET on canonical objects for source reads, and dedicated query endpoints for projections like feed, search, and top K.