🔍 REST API Design Review

Identifying problems & applying best-practice corrections to four proposed endpoints

⚠ 4 Endpoints Reviewed ✓ All Issues Corrected REST / HTTP 1.1
🐛
Design Issues Found
12
Issues Resolved
12
📡
Endpoints Audited
4
📋
Status Codes Defined
10
📐 Core REST Principles Applied
🔤
Nouns, not verbsURLs identify resources; HTTP methods express actions.
🔡
Lowercase & hyphensUse /user-profiles, never camelCase or underscores.
📦
Plural collections/users for a collection, /users/5 for a member.
🔀
Correct HTTP verbsGET=read, POST=create, PUT/PATCH=update, DELETE=delete.
🚦
Meaningful status codes201 Created, 204 No Content, 400 Bad Request, etc.
🔒
No sensitive data in URLUse request body or headers for sensitive params.
🔄 Endpoint-by-Endpoint Analysis
1
GET /getUsers List all users
❌ Original
GET/getUsers
✅ Corrected
GET/users
⚠ Issues Identified
  • Verb in URL pathgetUsers embeds the action as a verb. REST URLs must represent resources (nouns), not actions. The HTTP method (GET) already communicates the action.
  • Non-plural resource name — Collections should use the plural form: /users not /user.
  • Action-based naming — Naming routes after CRUD operations (get, create, delete) couples the URL to implementation details and breaks discoverability.
✅ Fixes Applied
  • Removed the get verb — the HTTP GET method already expresses retrieval.
  • Renamed to plural /users to represent the collection resource.
  • Optional query parameters such as ?page=1&limit=20&sort=name can be appended for pagination and filtering.
🚦 Expected Status Codes
200 OK — users array returned 401 Unauthorized — missing auth 403 Forbidden — insufficient permissions 500 Internal Server Error
2
POST /user/delete/5 Delete user #5
❌ Original
POST/user/delete/5
✅ Corrected
DELETE/users/5
⚠ Issues Identified
  • Wrong HTTP method — Using POST to delete a resource is semantically incorrect. DELETE is the designated method for resource removal and is idempotent by specification.
  • Verb in URL path/delete should never appear in a REST path. The DELETE HTTP method communicates this intent.
  • Singular resource name/user should be /users (plural collection), with the ID identifying the specific member.
  • Non-idempotent semanticsPOST is not idempotent; calling it multiple times can produce different results. DELETE is idempotent — deleting an already-deleted resource returns 404 gracefully.
✅ Fixes Applied
  • Changed method to DELETE — semantically correct and idempotent.
  • Removed /delete segment from the path entirely.
  • Changed /user/users for consistent plural collection naming.
  • Resource identifier /5 remains as the path parameter targeting the specific user.
🚦 Expected Status Codes
204 No Content — deleted successfully 404 Not Found — user doesn't exist 401 Unauthorized 403 Forbidden
3
GET /createUser?name=Jo Create a user
❌ Original
GET/createUser?name=Jo
✅ Corrected
POST/users
Body: {"name":"Jo","email":"..."}
⚠ Issues Identified
  • GET used for a state-changing operationGET must be safe (read-only, no side effects). Creating a resource is a side effect and must use POST.
  • Sensitive/payload data in the query string — Query strings are stored in server logs, browser history, and proxy caches. User data (name, email, password) must travel in the request body over HTTPS.
  • Verb in URL pathcreateUser mixes action + resource. The correct pattern is POST /usersPOST to the collection.
  • Caching hazard — GET requests are cacheable by default. A cached "create user" request could silently replay, causing duplicate records.
✅ Fixes Applied
  • Changed method to POST — the correct verb for creating a new resource in a collection.
  • Moved all user data to the JSON request body, keeping it out of URLs and logs.
  • URL simplified to /users — POSTing to the collection is the standard REST creation pattern.
  • Response should include a Location header pointing to the newly created resource, e.g. Location: /users/42.
🚦 Expected Status Codes
201 Created — new user created 400 Bad Request — invalid/missing fields 409 Conflict — email already exists 422 Unprocessable Entity — validation error
4
PUT /updateAllUsers Bulk update users
❌ Original
PUT/updateAllUsers
✅ Corrected (options)
PATCH/users  — bulk partial update
PUT/users/5  — full replace single user
⚠ Issues Identified
  • Verb in URL pathupdate is an action; it belongs in the HTTP method, not the URL.
  • Ambiguous scope — "All" is dangerous — Bulk operations must be explicit and intentional. A single endpoint silently modifying every user record is an extreme data-integrity risk with no scoping mechanism.
  • Wrong semantics for partial updatesPUT implies a full replacement of the resource. If only some fields change, PATCH is the correct method and communicates partial update intent clearly.
  • camelCase path — REST paths should be lowercase-with-hyphens. updateAllUsers uses camelCase which is inconsistent and not URL-friendly.
✅ Fixes Applied
  • Removed update verb — the HTTP method conveys this.
  • For updating a single user: PUT /users/{id} (full replace) or PATCH /users/{id} (partial update).
  • For bulk updates: PATCH /users with a JSON body array is acceptable, but should require explicit IDs in the payload — never an implicit "all".
  • Consider adding a filter query parameter for scoped bulk updates: PATCH /users?role=admin.
🚦 Expected Status Codes
200 OK — updated, returns updated resource(s) 204 No Content — updated, no body returned 400 Bad Request — malformed body 404 Not Found — user ID not found
📊 Quick-Reference: Before vs After
# Original Endpoint Corrected Endpoint Primary Issues Success Code
1 GET /getUsers GET /users Verb in URL, singular name 200 OK
2 POST /user/delete/5 DELETE /users/5 Wrong method, verb in URL, singular 204 No Content
3 GET /createUser?name=Jo POST /users GET for mutation, data in URL, verb in path 201 Created
4 PUT /updateAllUsers PATCH /users/{id} Verb in URL, wrong method, unsafe bulk op 200 OK
📚 REST Best-Practices Reference

🔤 URL Design Rules

  • Use nouns, never verbs in paths
  • Plural names for collections (/users)
  • Lowercase letters and hyphens only
  • Hierarchical nesting: /users/5/posts
  • No trailing slashes
  • No file extensions (.json)

🔀 HTTP Method Semantics

  • GET — Read, safe, idempotent, cacheable
  • POST — Create, not idempotent
  • PUT — Full replace, idempotent
  • PATCH — Partial update, idempotent
  • DELETE — Remove, idempotent
  • HEAD / OPTIONS — Metadata / CORS

🚦 Status Code Cheat Sheet

  • 200 OK — general success
  • 201 Created — resource created
  • 204 No Content — success, no body
  • 400 Bad Request — client error
  • 401 Unauthorized — auth required
  • 403 Forbidden — auth insufficient
  • 404 Not Found — resource missing
  • 409 Conflict — state conflict
  • 422 Unprocessable — validation fail
  • 500 Internal Server Error

🔒 Security Considerations

  • Never put sensitive data in query strings
  • Always use HTTPS in production
  • Use Authorization headers for tokens
  • Validate and sanitize all inputs
  • Rate-limit write endpoints
  • Require explicit scoping for bulk ops

📦 Request / Response Patterns

  • Return Location header on 201
  • Use JSON consistently (Content-Type)
  • Wrap collections: {"data":[], "meta":{}}
  • Include pagination metadata
  • Use consistent error object shape
  • Support If-Match for optimistic locking

🔢 Versioning Strategies

  • URL prefix: /v1/users (most common)
  • Header: Accept: application/vnd.api+json;v=1
  • Query param: /users?version=1
  • Never break existing contracts
  • Deprecate with sunset headers
  • Document all versions clearly