What Is REST?
REST (Representational State Transfer) is an architectural style for designing networked applications, defined by Roy Fielding in his 2000 doctoral dissertation. It is not a protocol or standard — it is a set of constraints that, when applied to web services, make them scalable, simple, and reliable.
REST has become the dominant approach for web APIs because it leverages the existing HTTP protocol, making it easy to understand and implement. When people say “REST API” or “RESTful API,” they mean a web service that follows REST architectural principles.
REST vs. Other Styles
Before REST became dominant, most web services used SOAP (Simple Object Access Protocol), which required XML messages, strict schemas, and was often complex. REST simplified everything by using standard HTTP methods and allowing flexible data formats (primarily JSON).
| Feature | REST | SOAP | GraphQL |
|---|---|---|---|
| Protocol | HTTP | HTTP, SMTP, etc. | HTTP |
| Data format | JSON, XML, etc. | XML only | JSON |
| Contract | Optional (OpenAPI) | Required (WSDL) | Required (Schema) |
| Learning curve | Low | High | Medium |
| Caching | Built-in (HTTP) | Custom | Custom |
The Six REST Constraints
Roy Fielding defined six constraints that an API must follow to be considered RESTful. Understanding these is essential for testing because violations of these constraints often indicate design problems or potential bugs.
1. Client-Server Separation
The client (frontend) and server (backend) must be independent. The client only knows how to make requests; the server only knows how to process them and return responses. This separation allows each to evolve independently.
Testing implication: You can test the API independently of any specific client. A mobile app, web app, or cURL command should all get the same results for the same request.
2. Stateless
Each request from the client must contain all the information the server needs to process it. The server does not store session state between requests. Authentication tokens, user preferences, and any context must be sent with every request.
Testing implication: You can send any request in isolation without needing to send previous requests first (except for data dependencies). Each request should be independently verifiable.
3. Cacheable
Responses must indicate whether they can be cached. Proper caching reduces server load and improves performance. HTTP provides cache headers (Cache-Control, ETag, Last-Modified) to manage this.
Testing implication: Verify that cache headers are set correctly. GET requests for static data should be cacheable; POST/PUT/DELETE responses typically should not be.
4. Uniform Interface
This is the most distinctive REST constraint. It has four sub-constraints:
- Resource identification — each resource has a unique URI (e.g.,
/users/42) - Resource manipulation through representations — clients work with representations (JSON, XML) of resources, not the resources directly
- Self-descriptive messages — each message includes enough information to describe how to process it (Content-Type, methods)
- HATEOAS — responses include links to related actions
5. Layered System
The client cannot tell whether it is connected directly to the server or to an intermediary (load balancer, CDN, API gateway). Each layer only knows about the layer it interacts with.
Testing implication: Test through the actual infrastructure (including load balancers and API gateways) in staging environments, not just against the bare server.
6. Code on Demand (Optional)
Servers can optionally send executable code (like JavaScript) to clients. This is the only optional constraint and is rarely used in API contexts.
Resource Design and URL Structure
One of the most visible aspects of REST is how URLs are structured. RESTful URLs represent resources (nouns), not actions (verbs).
Resource Naming Conventions
Good (RESTful):
GET /users → List all users
GET /users/42 → Get user 42
POST /users → Create a new user
PUT /users/42 → Update user 42
DELETE /users/42 → Delete user 42
Bad (not RESTful):
GET /getUsers
POST /createUser
GET /getUserById?id=42
POST /deleteUser
Nested Resources
When resources have relationships, nest them logically:
GET /users/42/orders → Orders belonging to user 42
GET /users/42/orders/7 → Order 7 of user 42
POST /users/42/orders → Create an order for user 42
Query Parameters for Filtering
Use query parameters for filtering, sorting, and pagination — not for identifying resources:
GET /users?role=admin → Filter users by role
GET /users?sort=name&order=asc → Sort users by name
GET /users?page=2&limit=20 → Paginate results
GET /orders?status=pending&from=2025-01-01 → Combined filters
REST Maturity Model (Richardson)
Leonard Richardson defined a maturity model that classifies APIs by how well they implement REST principles. This is useful for evaluating APIs you test.
Level 0: The Swamp of POX
Single endpoint, single HTTP method (usually POST), actions encoded in the request body. Essentially RPC over HTTP.
POST /api
Body: { "action": "getUser", "userId": 42 }
Level 1: Resources
Different URLs for different resources, but still using a single HTTP method.
POST /users/42
Body: { "action": "get" }
Level 2: HTTP Methods
Proper use of HTTP methods (GET, POST, PUT, DELETE) with resource-based URLs. Most APIs that claim to be RESTful are at this level.
GET /users/42
POST /users
PUT /users/42
DELETE /users/42
Level 3: HATEOAS (Hypermedia Controls)
Responses include links to related actions and resources. This is the highest level of REST maturity and is rarely fully implemented.
{
"id": 42,
"name": "Alice",
"links": [
{ "rel": "self", "href": "/users/42" },
{ "rel": "orders", "href": "/users/42/orders" },
{ "rel": "update", "href": "/users/42", "method": "PUT" },
{ "rel": "delete", "href": "/users/42", "method": "DELETE" }
]
}
Testing REST Compliance
When testing an API, evaluate its adherence to REST principles with this checklist:
URL Structure Tests
- URLs use nouns (resources), not verbs (actions)
- Resources are plural (
/users, not/user) - Nested resources reflect real relationships
- Query parameters are used for filtering, not resource identification
- URLs are lowercase and use hyphens for readability (
/order-items, not/orderItems)
HTTP Method Tests
- GET requests never modify data
- POST creates new resources and returns 201
- PUT replaces the entire resource
- PATCH partially updates a resource
- DELETE removes a resource and returns 204 or 200
Statelessness Tests
- Requests work without prior session setup
- Authentication is sent with each request (not stored server-side)
- Sending the same request twice produces the same result (idempotency for GET, PUT, DELETE)
Response Format Tests
- Content-Type header matches the actual response format
- JSON responses follow consistent structure
- Error responses include meaningful messages and proper status codes
- Collection responses include pagination metadata
Common REST Anti-Patterns
Knowing what to look for when testing:
| Anti-Pattern | Example | Should Be |
|---|---|---|
| Verbs in URLs | POST /createUser | POST /users |
| Tunneling through POST | POST /api?action=delete&id=42 | DELETE /api/resources/42 |
| Ignoring status codes | Always returning 200 | Using 201, 204, 400, 404, etc. |
| Session-based state | Requiring login endpoint first | Token in Authorization header |
| Inconsistent naming | /users/42 but /getOrders | Consistent noun-based URLs |
Hands-On Exercise
Analyze these three public APIs for REST compliance:
JSONPlaceholder (
https://jsonplaceholder.typicode.com)- Send GET /posts, GET /posts/1, POST /posts, PUT /posts/1, DELETE /posts/1
- Rate its REST maturity level (0-3)
GitHub API (
https://api.github.com)- Examine the response from GET
/— does it include HATEOAS links? - Check
/repos/{owner}/{repo}/issuesfor proper resource nesting
- Examine the response from GET
Create a REST compliance report covering: URL conventions, HTTP method usage, response codes, statelessness, and HATEOAS presence
Key Takeaways
- REST is an architectural style with six constraints: client-server, stateless, cacheable, uniform interface, layered system, and code on demand
- RESTful URLs use nouns (resources) rather than verbs (actions) and follow consistent patterns
- The Richardson Maturity Model classifies APIs from Level 0 (RPC-style) to Level 3 (full HATEOAS)
- Most production APIs operate at Level 2 — proper resources and HTTP methods
- Testing REST compliance helps identify design issues, inconsistencies, and potential bugs early