What is a REST API? — Representational State Transfer Explained
Definition
REST (Representational State Transfer) is an architectural style for designing networked applications. A REST API (also called a RESTful API) is an API that conforms to the constraints of the REST architectural style, using HTTP as the communication protocol to perform operations on resources. Resources are typically represented in JSON or XML format and are accessed via standard HTTP methods.
REST was introduced by Roy Fielding in his 2000 doctoral dissertation and has become the dominant API design standard for web services due to its simplicity, scalability, and stateless nature.
REST Principles (Architectural Constraints)
A true RESTful API must satisfy the following six constraints:
1. Stateless
Each request from a client must contain all the information the server needs to process it. The server does not store any client context between requests. Session state is kept entirely on the client.
2. Client-Server
The client and server are separated by a uniform interface. This separation allows each to evolve independently — the client doesn't need to know about server-side storage, and the server doesn't need to know about the client's UI.
3. Cacheable
Responses must define themselves as cacheable or non-cacheable. Caching reduces the number of client-server interactions and improves performance. HTTP headers like Cache-Control, ETag, and Expires manage caching behavior.
4. Uniform Interface
The uniform interface simplifies the architecture by defining a consistent way to interact with resources. It includes:
- Resource identification in requests (URIs)
- Resource manipulation through representations
- Self-descriptive messages (headers, status codes)
- HATEOAS (Hypermedia as the Engine of Application State) — links in responses guide clients to related actions
5. Layered System
The architecture can be composed of hierarchical layers (load balancers, proxies, gateways, caches). A client cannot normally tell whether it is connected directly to the end server or an intermediary.
6. Code on Demand (Optional)
Servers can temporarily extend client functionality by transferring executable code (e.g., JavaScript). This is the only optional constraint.
HTTP Methods
REST APIs use standard HTTP methods to perform CRUD (Create, Read, Update, Delete) operations on resources:
| Method | CRUD Equivalent | Description | Idempotent | Safe |
|---|---|---|---|---|
| GET | Read | Retrieve a resource | ✅ | ✅ |
| POST | Create | Create a new resource | ❌ | ❌ |
| PUT | Update/Replace | Replace an entire resource | ✅ | ❌ |
| PATCH | Partial Update | Partially modify a resource | ❌ | ❌ |
| DELETE | Delete | Remove a resource | ✅ | ❌ |
Idempotent means multiple identical requests produce the same result as a single request. Safe means the request does not modify server state.
GET Example
GET /api/users/1 HTTP/1.1
Host: api.example.com
Accept: application/json{
"id": 1,
"name": "Alice Johnson",
"email": "alice@example.com",
"role": "admin"
}POST Example
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "Bob Smith",
"email": "bob@example.com",
"role": "user"
}HTTP/1.1 201 Created
Location: /api/users/2
{
"id": 2,
"name": "Bob Smith",
"email": "bob@example.com",
"role": "user"
}PUT Example
PUT /api/users/2 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"name": "Bob Smith",
"email": "bob@newdomain.com",
"role": "admin"
}PATCH Example
PATCH /api/users/2 HTTP/1.1
Host: api.example.com
Content-Type: application/json
{
"email": "bob@newdomain.com"
}DELETE Example
DELETE /api/users/2 HTTP/1.1
Host: api.example.comHTTP/1.1 204 No ContentHTTP Status Codes
REST APIs use standard HTTP status codes to indicate the result of a request:
Success Codes (2xx)
| Code | Meaning | When to Use |
|---|---|---|
| 200 OK | Request succeeded | GET, PUT, PATCH (response body included) |
| 201 Created | Resource created | POST (response includes Location header) |
| 202 Accepted | Request accepted for async processing | Background jobs, async operations |
| 204 No Content | Request succeeded, no response body | DELETE, PUT (when no body needed) |
Client Error Codes (4xx)
| Code | Meaning | When to Use |
|---|---|---|
| 400 Bad Request | Malformed request syntax | Invalid JSON, missing fields, validation errors |
| 401 Unauthorized | Authentication required | Missing or invalid authentication credentials |
| 403 Forbidden | Authenticated but not authorized | Insufficient permissions for the resource |
| 404 Not Found | Resource doesn't exist | Invalid endpoint or resource ID |
| 405 Method Not Allowed | HTTP method not supported | POST on a read-only endpoint |
| 409 Conflict | Resource state conflict | Duplicate resource, version conflict |
| 422 Unprocessable Entity | Semantic validation failure | Business rule violations |
| 429 Too Many Requests | Rate limit exceeded | Too many requests in a time window |
Server Error Codes (5xx)
| Code | Meaning | When to Use |
|---|---|---|
| 500 Internal Server Error | Generic server error | Unexpected server-side failure |
| 502 Bad Gateway | Upstream server error | Proxy/gateway can't reach upstream |
| 503 Service Unavailable | Server temporarily unavailable | Maintenance, overload |
| 504 Gateway Timeout | Upstream timeout | Upstream server didn't respond in time |
Request / Response Structure
Request Components
POST /api/users?page=2&limit=10 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json
Accept: application/json
Cache-Control: no-cache
{
"name": "Charlie",
"email": "charlie@example.com"
}
| Component | Example | Description |
|---|---|---|
| Method | POST |
HTTP method |
| Path | /api/users |
Resource endpoint |
| Query Parameters | ?page=2&limit=10 |
Filtering, pagination |
| Headers | Authorization, Content-Type |
Metadata, auth, caching |
| Body | {"name": "Charlie"} |
Data payload (POST, PUT, PATCH) |
Response Components
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/users/3
Cache-Control: no-cache
X-Request-Id: a1b2c3d4
{
"id": 3,
"name": "Charlie",
"email": "charlie@example.com",
"createdAt": "2025-06-15T10:30:00Z"
}
| Component | Example | Description |
|---|---|---|
| Status Line | HTTP/1.1 201 Created |
Protocol version + status code |
| Headers | Content-Type, Location |
Metadata about the response |
| Body | JSON/XML response | Resource representation |
REST vs GraphQL vs SOAP
| Aspect | REST | GraphQL | SOAP |
|---|---|---|---|
| Protocol | HTTP/HTTPS | HTTP/HTTPS | HTTP, SMTP, JMS, etc. |
| Data Format | JSON, XML, YAML | JSON | XML only |
| Endpoint Model | Multiple endpoints (one per resource) | Single endpoint | Single endpoint (service) |
| Data Fetching | Fixed response structure | Client-specified fields | Fixed response structure |
| Over-fetching | Common | None (client controls fields) | Common |
| Under-fetching | Common (requires multiple requests) | Solved (nested queries) | Common |
| Caching | Built-in (HTTP caching) | Requires custom setup | Built-in (HTTP/WS) |
| Tooling | Mature, widely supported | Growing ecosystem | Mature (enterprise) |
| Complexity | Low to medium | Medium to high | High |
| Learning Curve | Gentle | Moderate | Steep |
| Best For | Public APIs, CRUD, microservices | Complex UIs, dashboards, mobile | Enterprise, banking, legacy systems |
When to choose REST: You want simplicity, universal caching, a mature ecosystem, and your API is resource-oriented with predictable data shapes.
When to choose GraphQL: You need flexible frontend data fetching, aggregate data from multiple sources, or have complex nested data requirements.
When to choose SOAP: You're in a regulated industry (finance, healthcare) requiring built-in security standards (WS-Security), ACID compliance, or formal contract-first development.
Authentication Methods
REST APIs commonly use the following authentication methods:
Bearer Token (JWT)
The most common modern approach. The client obtains a token and sends it in the Authorization header.
GET /api/users HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6ImFkbWluIn0.tknf5I3N-G8iXGJkZE5GQNcqZORnWUPN0H_PJFikxUcFlow: Login → Server issues JWT → Client stores JWT → Client sends JWT with each request → Server verifies JWT signature
API Key
A simpler approach where each client is issued a unique key that is sent with every request.
GET /api/users HTTP/1.1
Host: api.example.com
X-API-Key: abc123def456Or as a query parameter:
GET /api/users?api_key=abc123def456 HTTP/1.1
Host: api.example.comPros: Simple to implement. Cons: Less secure (keys are often long-lived, hard to rotate).
Basic Authentication
The client sends username:password encoded as Base64 in the Authorization header.
GET /api/users HTTP/1.1
Host: api.example.com
Authorization: Basic YWxpY2U6cGFzc3dvcmQxMjM=Warning: Base64 is not encryption — anyone can decode it. Always use Basic auth over HTTPS only.
Comparison
| Method | Security | Complexity | Use Case |
|---|---|---|---|
| Bearer Token (JWT) | High (with HTTPS + short expiry) | Medium | Modern APIs, SPAs, mobile apps |
| API Key | Medium | Low | Public APIs, server-to-server |
| Basic Auth | Low (without HTTPS) | Very Low | Legacy systems, quick prototypes |
RESTful API Design Best Practices
1. Use Nouns for Resources
✅ GET /users — List users
✅ GET /users/123 — Get a specific user
✅ POST /users — Create a user
✅ DELETE /users/123 — Delete a user
❌ GET /getUsers
❌ POST /createUser
❌ GET /users?delete=true
2. Use Plural Resource Names
✅ /users, /orders, /products
❌ /user, /order, /productInfo
3. Nest Related Resources Logically
GET /users/123/orders — Orders for user 123
GET /users/123/orders/456 — Specific order for user 123
POST /users/123/orders — Create order for user 123
4. Consistent Error Responses
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is already in use",
"details": [
{ "field": "email", "issue": "must be unique" }
]
}
}5. Support Pagination, Filtering, and Sorting
GET /users?page=2&limit=20&sort=-createdAt&role=admin
{
"data": [...],
"meta": {
"page": 2,
"limit": 20,
"total": 150,
"totalPages": 8
}
}6. Version Your API
✅ /api/v1/users
✅ /api/v2/users
❌ /api/users (no version)
Use URL-based versioning (/v1/, /v2/) or header-based versioning (Accept: application/vnd.api.v1+json).
7. Use Proper HTTP Methods and Status Codes
Don't use GET to delete resources or return 200 for errors. Use the correct status codes consistently.
8. Secure Your API
- Always use HTTPS
- Implement rate limiting
- Validate and sanitize all input
- Use proper authentication (JWT, API keys)
- Apply CORS policies correctly
- Never expose internal implementation details
9. Document Your API
Provide clear documentation (OpenAPI 3.x) so consumers know how to interact with your endpoints. Use tools like LangStop's OpenAPI Editor.
LangStop API Tools
- REST API Client — Send HTTP requests and test API endpoints
- API Mock Response Generator — Generate realistic mock JSON responses
- WebSocket Client — Test WebSocket connections in real-time
- OpenAPI Editor — Design and validate OpenAPI 3.x specifications
- JWT Encoder — Create and sign JWT tokens
- JWT Decoder — Decode and inspect JWT tokens
- URL Encoder — Encode URL parameters and special characters