Resources vs representations
A resource is an abstraction your API exposes — a thing you can name and talk about. Examples: an order, a customer, a collection of orders, a subscription on an account.
A representation is a snapshot of resource state in a concrete format: JSON, XML, HTML, protobuf. Clients transfer representations; they do not download “the order itself” as a Platonic object. The same order might appear as JSON for your app and as HTML for a browser-based admin tool — two representations, one resource.
This distinction matters in interviews when someone asks “what is the resource?” vs “what does the JSON look like?” The resource is the concept; the representation is the bytes on the wire.
URIs identify resources
The URI (path, plus query when filtering) identifies which resource or collection you mean:
/orders
/orders/42
/customers/9
/customers/9/orders
Good paths use nouns for resources. Verbs belong in HTTP methods (GET, POST, PUT, PATCH, DELETE), not in path segments like /getOrder or /createUser.
Naming conventions
Use nouns, not verbs
| Prefer | Avoid |
|---|---|
GET /orders/42 |
GET /getOrder?id=42 |
POST /orders |
POST /createOrder |
DELETE /orders/42 |
POST /orders/42/delete |
Action-oriented endpoints still appear in real APIs. POST /orders/99/cancel is REST-ish when modeled as a sub-resource or state transition on order 99 — the noun is still orders/99; cancel names a command resource or subordinate action. Prefer sub-resources over bare verbs at the root (POST /cancelOrder).
Plural collection names
Collections are usually plural: /orders, /users, /invoices. A single item is /orders/{id}. Consistency across the API matters more than the singular-vs-plural debate — pick plural for collections and stick to it.
Nesting depth
Nest paths to express ownership or containment when it aids clarity:
/customers/9/orders — orders belonging to customer 9
/orders/42/line-items — line items on order 42
Rules of thumb:
- Two levels of nesting (
/a/{id}/b) is common and readable. - Three levels (
/a/{id}/b/{id}/c) is acceptable when the domain genuinely requires it. - Deep nesting (
/a/1/b/2/c/3/d/4) hurts clients and duplicates parent ids in every URL. Prefer flat resources with query filters:GET /line-items?order_id=42.
If the child can exist independently or is queried across parents, expose it at the top level: GET /orders/42 and GET /line-items?order_id=42 rather than forcing every read through a long path.
Identifiers in paths, filters in query strings
- Path — identity of a specific resource:
/orders/42. - Query — filtering, sorting, pagination, sparse fieldsets:
/orders?status=open&sort=-created_at&limit=20.
Search that does not fit a simple filter sometimes becomes POST /search or GET /orders?q=... — pragmatic, not pure REST. See Methods & Idempotency for when POST search is reasonable.
Representations and content negotiation
Clients and servers agree on representation format via Content-Type and Accept headers. Most JSON APIs fix on application/json and skip negotiation. Mentioning content negotiation in an interview shows you know representations are negotiable even if your team never ships XML.
Versioning sometimes rides headers (Accept: application/vnd.example.v2+json) instead of path prefixes — covered in Versioning, Pagination & Idempotency.
Collections and empty states
GET /orders returns a collection representation — often { "items": [...], "next_cursor": "..." } rather than a bare array, so pagination metadata has a home.
GET /orders/999999 when the id does not exist → 404 Not Found (or 403 when hiding existence is a security requirement).
Creating adds a member: POST /orders with a body → 201 Created and a Location header pointing to /orders/{new-id}.
Interview framing
“How do you design URLs for a nested domain?” — Nouns in paths, plural collections, shallow nesting for ownership, flatten when queries cross branches. Verbs in HTTP methods; sub-resources for domain actions like cancel or approve.
“Resource vs representation?” — The order is the resource; the JSON { "id": 42, "total": 1999 } is a representation clients cache, validate, and send back on updates.
“Is /orders/42/cancel RESTful?” — It is REST-ish: POST to a sub-resource naming an action on order 42. Alternatives: PATCH with { "status": "cancelled" } on /orders/42, or a state machine documented in your API spec.
Next: Methods & Idempotency — which verb for which operation, and why retries care.