Full analysis of every violation with corrected endpoints and REST principles
GET /getUsers
GET /users
/user-profiles) or simple lowercase nouns.
/users.
getUsers()) rather than a REST resource. REST is resource-oriented, not action-oriented.
GET /users — The HTTP verb GET already declares the intent to retrieve. The URI /users identifies the resource collection (plural noun, lowercase). No verb needed, no ambiguity.
To retrieve a specific user: GET /users/{id}. To filter: GET /users?role=admin&status=active.
POST /user/delete/5
DELETE /users/5
/users/5.
/user/ uses a singular noun for a collection segment. REST convention requires plural nouns for collections: /users/. Singular is only used when the resource is a singleton (e.g., /users/5/profile).
/user/ while endpoint 1 uses /getUsers. The collection path must be consistent across all operations on the same resource type.
DELETE /users/5 — DELETE is the correct HTTP method for removal. It is idempotent (calling it twice is safe). The URI /users/5 cleanly identifies the specific resource: user with ID 5, inside the users collection.
Expected responses: 204 No Content on success, 404 Not Found if user doesn't exist, 409 Conflict if deletion is blocked by a dependency.
GET /createUser?name=Jo
POST /users
Body: { "name": "Jo" }
/users) already communicates "create a new user in this collection".
?name=Jo in a GET request exposes resource data in the URL. This data will appear in server logs, browser history, and referrer headers — a security and privacy risk. Creation data belongs in the request body of a POST request.
POST /users with body {"name": "Jo"} — POST to a collection creates a new member. Data travels in the request body (not the URL), keeping it out of logs and caches. POST is non-idempotent, which correctly signals that each call may create a new resource.
Expected responses: 201 Created with a Location: /users/6 header pointing to the new resource, plus the created resource in the body.
PUT /updateAllUsers
PATCH /users
Body: { "status": "inactive" }
/users (the collection).
PATCH /users (all), PATCH /users?status=active (filtered subset). Encoding scope in the URI path creates an explosion of endpoint variants.
PATCH /users with a partial update body — PATCH applies partial modifications. Applied to the collection URI /users, it signals a bulk partial update. Filters can be added via query params: PATCH /users?department=engineering.
If truly replacing all users with a complete new dataset, use PUT /users with the full collection in the body. Expected responses: 200 OK with update summary, or 204 No Content.
| Endpoint | Violation | Category | Severity |
|---|---|---|---|
GET /getUsers |
Verb "get" in URI path | Resource Naming | High |
GET /getUsers |
camelCase URI naming | Naming Convention | Medium |
GET /getUsers |
RPC-style design | Architecture | High |
GET /getUsers |
Inconsistent plural naming vs other endpoints | Consistency | Medium |
POST /user/delete/5 |
POST used instead of DELETE | HTTP Method | High |
POST /user/delete/5 |
Verb "delete" in URI path | Resource Naming | High |
POST /user/delete/5 |
Singular "user" instead of plural "users" | Naming Convention | Medium |
POST /user/delete/5 |
Broken idempotency semantics | HTTP Semantics | High |
POST /user/delete/5 |
Inconsistent collection name vs endpoint 1 | Consistency | Medium |
GET /createUser?name=Jo |
GET used for state-changing operation | HTTP Method | High |
GET /createUser?name=Jo |
Verb "create" in URI path | Resource Naming | High |
GET /createUser?name=Jo |
Resource data exposed in query string | Security / Data Handling | High |
GET /createUser?name=Jo |
Mutation via cacheable GET request | HTTP Semantics | High |
PUT /updateAllUsers |
PUT used instead of PATCH for partial update | HTTP Method | High |
PUT /updateAllUsers |
Verb "update" + scope "All" in URI path | Resource Naming | High |
URIs identify resources (things), not operations (actions). Actions are expressed through HTTP methods. A URI like /deleteUser or /getUsers encodes the action in the path — this is an RPC pattern, not REST. Every endpoint in this API violates this principle. Correct: GET /users, DELETE /users/5.
GET = safe + idempotent, retrieves state, never modifies it.
POST = creates a new resource in a collection, non-idempotent.
PUT = replaces a resource completely, idempotent.
PATCH = partially updates a resource, not necessarily idempotent.
DELETE = removes a resource, idempotent.
Using POST to delete, or GET to create, breaks the HTTP contract that clients, proxies, and caches rely on.
Collections are plural: /users, /orders, /products. Individual resources are addressed by ID within the collection: /users/5. Mixing singular and plural (/user vs /users) across endpoints for the same resource type breaks consistency and predictability.
Safe methods (GET, HEAD, OPTIONS) must not change server state. Browsers, prefetch engines, and link crawlers call GET freely. A GET that creates data is a security and data integrity disaster.
Idempotent methods (GET, PUT, DELETE, HEAD) must produce the same result when called multiple times. This enables safe retries. POST and PATCH are not idempotent by definition.
One of REST's core constraints. The interface between client and server must be uniform and predictable. This means consistent resource naming, consistent use of HTTP methods, consistent response structures, and consistent use of status codes. An API where you must read documentation for every endpoint because each follows different conventions is not RESTful.
Query parameters filter, sort, or paginate a resource collection. They should not encode business logic scope into the URI path. /updateAllUsers encodes "all" as scope in the path. The REST way: PATCH /users (all), PATCH /users?status=active (filtered). This avoids URI proliferation.
Data used to create or update a resource belongs in the request body, not the URL. Query strings are for filtering/sorting existing resources. Putting creation data in a GET query string (?name=Jo) exposes sensitive data in server logs, browser history, and referrer headers, and breaks caching semantics.
REST URIs should use: lowercase letters, hyphens (not underscores or camelCase) for multi-word names, no trailing slashes, and no file extensions. Examples: /user-profiles not /userProfiles or /user_profiles. Consistency across the entire API is more important than any single convention choice.
| Method | Purpose | Safe? | Idempotent? | Request Body? | Success Code |
|---|---|---|---|---|---|
| GET | Retrieve a resource or collection | ✔ Yes | ✔ Yes | ✘ No | 200 OK |
| POST | Create a new resource in a collection | ✘ No | ✘ No | ✔ Yes | 201 Created |
| PUT | Replace a resource completely | ✘ No | ✔ Yes | ✔ Yes | 200 OK / 204 |
| PATCH | Partially update a resource | ✘ No | ✘ No* | ✔ Yes | 200 OK / 204 |
| DELETE | Remove a resource | ✘ No | ✔ Yes | ✘ No | 204 No Content |
* PATCH can be made idempotent depending on implementation (e.g., set operations vs. increment operations).
| Operation | Original (Wrong) | Corrected |
|---|---|---|
| List all users | GET /getUsers |
GET /users |
| Get one user | Not provided | GET /users/{id} |
| Create a user | GET /createUser?name=Jo |
POST /users |
| Replace a user | Not provided | PUT /users/{id} |
| Partially update a user | Not provided | PATCH /users/{id} |
| Bulk partial update | PUT /updateAllUsers |
PATCH /users |
| Delete a user | POST /user/delete/5 |
DELETE /users/5 |