Courses › System Design › Core Concepts
API Design
REST, GraphQL and RPC; resource modeling, pagination, idempotency and versioning.
In most system design interviews you'll spend about five minutes on the API. That's not long, but it's where you turn requirements into something concrete — and a sloppy API makes every later step harder.
Choosing a style
[!INTERVIEW] Don't debate this for long Say "I'll use REST for the client-facing API" and move on. Only spend time here if the problem genuinely calls for something else.
Modeling resources
REST APIs are organized around resources (nouns) and HTTP methods (verbs):
GET /v1/events?city=seattle&date=2026-10-12 # search events
GET /v1/events/{eventId} # event details + seat map
POST /v1/events/{eventId}/reservations # hold seats
POST /v1/bookings # confirm a booking
GET /v1/bookings/{bookingId}Guidelines:
- Use plural nouns for collections; nest only when the relationship is strict (
/events/{id}/reservations). - Map methods to semantics: GET reads, POST creates, PUT replaces, PATCH partially updates, DELETE removes.
- Put filters, sorting and pagination in the query string; put the resource body in the request body.
- Derive the current user from the auth token, never from a body field.
Pagination
Never return unbounded lists.
- Offset pagination (
?offset=40&limit=20) is simple, but slow for deep pages and unstable when items are inserted while the user is paging. - Cursor pagination (
?cursor=eyJ0cyI6...&limit=20) encodes the position of the last item seen (e.g. its timestamp and ID). It stays fast at any depth and is stable under inserts. Use it for feeds and anything that changes frequently.
Idempotency
Clients retry. Networks drop responses. If a request that creates something is retried, you must not create it twice.
POST /v1/payments
Idempotency-Key: 9f1c2a7e-6b8d-4f0e-a1b2-3c4d5e6f7a8b
{ "amount": 4999, "currency": "usd", "source": "card_123" }The server stores the key with the result. A repeated key returns the stored result instead of charging again.
Errors and status codes
Return meaningful codes so clients can react correctly:
- 400 invalid input · 401 not authenticated · 403 not allowed · 404 not found
- 409 conflict (e.g. the seat is already reserved) · 429 rate limited (with
Retry-After) - 5xx — server errors; clients may retry these with backoff
Versioning and evolution
Put a version in the path (/v1/) or a header. Make additive, backward-compatible changes — new optional fields, new endpoints — and introduce a new version only for breaking changes.
Security essentials
- Authenticate with tokens (OAuth 2.0 / JWT) over HTTPS
- Authorize every request against the resource: can *this* user read *this* booking?
- Rate limit per user and per IP (see Design a Rate Limiter)
- Validate and bound all input sizes