Backend

REST API Design Best Practices

A REST API that technically works but doesn't follow established conventions is harder for every consumer of it to use correctly — including your own future self. These practices are what separate an API that feels predictable and easy to integrate against from one that requires constantly checking the docs for surprises.

Last updated 2026-09-08

1

Use nouns for resource URLs, not verbs

The HTTP method already expresses the action (GET, POST, PUT, DELETE) — the URL should identify the resource, not repeat the action in the path. This keeps the API predictable and consistent across every endpoint.

✓ DoPOST /users, GET /users/123, DELETE /users/123
✗ Don'tPOST /createUser, GET /getUser?id=123, POST /deleteUser
2

Use HTTP status codes correctly and consistently

Returning 200 OK for every response — including errors, communicated only through a message in the body — forces every consumer to parse the response body just to know if something went wrong. Proper status codes (400 for bad input, 401/403 for auth issues, 404 for missing resources, 500 for server errors) let clients handle responses correctly using standard HTTP semantics.

3

Version your API from the start

An API with no versioning strategy has no safe way to make a breaking change without immediately breaking every existing consumer. Even a simple /v1/ prefix from day one gives you a clear path to introduce /v2/ later without disrupting clients still on the previous version.

4

Support pagination for any endpoint that can return an unbounded list

An endpoint that returns 'all users' without pagination works fine with 50 test records and becomes a serious performance and reliability problem once there are 500,000 real ones. Build pagination in from the start, even if early usage doesn't seem to need it yet.

5

Be consistent with naming conventions across every endpoint

Mixing camelCase and snake_case for field names across different endpoints, or being inconsistent about singular versus plural resource names, forces every consumer to remember exceptions rather than rely on a predictable pattern. Pick one convention and apply it everywhere.

6

Return meaningful error responses, not just a status code

A 400 response with no body, or a body containing just {"error": true}, gives a client nothing to act on or display to a user. Include a clear, specific error message and, where useful, a machine-readable error code that a client can handle programmatically.

✓ Do{ "error": { "code": "INVALID_EMAIL", "message": "Email address is not valid." } }
7

Document authentication requirements clearly, and never require secrets in the URL

API keys or tokens passed as URL query parameters end up in server logs, browser history, and referrer headers — all real, common ways they leak. Use an Authorization header instead, and be explicit in documentation about exactly what authentication each endpoint requires.

Common Mistakes to Avoid

  • Verb-based URLs (/getUser, /createOrder) instead of resource-based nouns with proper HTTP methods
  • Returning 200 OK for error responses, forcing clients to parse the body to detect failure
  • No API versioning strategy, making any future breaking change immediately disruptive
  • No pagination on list endpoints, which becomes a real performance problem as data grows
  • Inconsistent field naming (camelCase in one endpoint, snake_case in another)
  • Passing API keys or tokens as URL query parameters instead of headers

Frequently Asked Questions

Should I always use plural resource names (/users vs /user)?

Plural is the more common, widely-recommended convention (/users for both the collection and /users/123 for a specific one), since it reads naturally for both the list and single-item cases. Whichever you pick, apply it consistently across every endpoint.

Is REST still the right choice over GraphQL in 2026?

Both remain widely used and each fits different needs — REST's simplicity and cacheability suit many APIs well, while GraphQL's flexible querying suits clients that need to fetch varied, nested data shapes efficiently. Neither has made the other obsolete; the right choice depends on the specific use case.

How should I version a REST API — URL path, header, or query param?

A URL path prefix (/v1/, /v2/) is the most common and most discoverable approach, since the version is visible directly in every request without needing to inspect headers, though header-based versioning is a legitimate alternative some APIs use.