Designing REST APIs

Resources, Verbs, Status Codes — the Conventions That Survive

Designing REST APIs

REST is a set of conventions, not a spec. Following them makes your API predictable.

4 min read Level 2/5 #nodejs#rest#api
What you'll learn
  • Model resources and collections
  • Pick the right HTTP method
  • Use status codes correctly

REST isn’t strict — it’s a set of conventions. Follow them and any other dev can read your API at a glance.

Resources and Collections

Group endpoints by resource (noun, plural):

/api/users           ← the collection
/api/users/42        ← one user
/api/users/42/posts  ← that user's posts

Avoid verbs in URLs (/getUser 👎). The verb is the HTTP method.

Methods → Operations

MethodOperationIdempotent?
GET /usersListyes
GET /users/42Read oneyes
POST /usersCreateno
PUT /users/42Full replaceyes
PATCH /users/42Partial update(yes-ish)
DELETE /users/42Deleteyes

Idempotent = the same request repeated has the same effect.

Status Codes That Matter

CodeMeaning
200OK — successful GET/PATCH/PUT
201Created — successful POST
204No Content — successful DELETE
301 / 302Redirect
400Bad Request — invalid input
401Unauthorized — no/bad auth
403Forbidden — authed but not allowed
404Not Found
409Conflict — duplicate, version mismatch
422Unprocessable — valid format, invalid data
429Too Many Requests
500Server Error
503Service Unavailable

Use 401 for “who are you” and 403 for “I know you, you can’t do this”. A frequent confusion.

Response Shape

Be consistent. A common pattern:

// success
{ "data": { "id": 42, "name": "Ada" } }

// list
{ "data": [...], "pagination": { "next": "...", "total": 100 } }

// error
{ "error": { "code": "user_not_found", "message": "..." } }

Pick a shape, stick to it. Mixed shapes drive clients crazy.

Pagination

For large collections, never return all rows:

GET /users?limit=20&cursor=abc

Cursor-based > offset-based. Offset (?page=2) breaks when rows are inserted/deleted. Cursors are stable.

Versioning

Bake a version into the URL or a header. URL is more common:

/api/v1/users
/api/v2/users

Bump v when you make a breaking change. Don’t break v1 silently.

Don’t Over-REST

Some operations don’t map cleanly to verbs+nouns. POST /sessions (login) is fine. POST /users/42/activate is fine. RPC-style endpoints (POST /trigger-recompute) are fine when REST gets contorted. Pragmatism over purity.

CORS →