
What is RESTful?
REST (Representational State Transfer) is an architectural style for designing networked applications. A RESTful API exposes resources (users, orders, posts, etc.) over HTTP using standard methods (GET, POST, PUT, PATCH, DELETE). The term and principles come from Roy Fielding’s 2000 doctoral dissertation, which defined the constraints that make web-scale systems reliable, evolvable, and performant.
Core REST Principles (with Real-World Examples)
Fielding’s REST defines a set of constraints. The more you follow them, the more “RESTful” your API becomes.
- Client–Server Separation
UI concerns (client) are separate from data/storage (server).
Example: A mobile banking app (client) calls the bank’s API (server) to fetch transactions. Either side can evolve independently. - Statelessness
Each request contains all information needed; the server stores no client session state.
Example:Authorization: Bearer <token>is sent on every request so the server doesn’t rely on sticky sessions. - Cacheability
Responses declare whether they can be cached to improve performance and scalability.
Example: Product catalog responses includeCache-Control: public, max-age=300so CDNs can serve them for 5 minutes. - Uniform Interface
A consistent way to interact with resources: predictable URLs, standard methods, media types, and self-descriptive messages.
Example:- Resource identification via URL:
/api/v1/orders/12345 - Standard methods:
GET /orders/12345(read),DELETE /orders/12345(remove) - Media types:
Content-Type: application/json - HATEOAS (optional): response includes links to related actions:
- Resource identification via URL:
{
"id": 12345,
"status": "shipped",
"_links": {
"self": {"href": "/api/v1/orders/12345"},
"track": {"href": "/api/v1/orders/12345/tracking"}
}
}
- Layered System
Clients don’t know if they’re talking to the origin server, a reverse proxy, or a CDN.
Example: Your API sits behind an API gateway (rate limiting, auth) and a CDN (caching), yet clients use the same URL. - Code on Demand (Optional)
Servers may return executable code to extend client functionality.
Example: A web client downloads JavaScript that knows how to render a new widget.
Expected Call & Response Features
- Resource-oriented URLs
- Collections:
/api/v1/users - Single resource:
/api/v1/users/42
- Collections:
- HTTP methods: GET (safe), POST (create), PUT (replace, idempotent), PATCH (partial update), DELETE (idempotent)
- HTTP status codes (see below)
- Headers:
Content-Type,Accept,Authorization,Cache-Control,ETag,Location - Bodies: JSON by default; XML/CSV allowed via
Accept - Idempotency: PUT and DELETE should be idempotent; POST is typically not; PATCH may or may not be, depending on design
- Pagination & Filtering:
GET /orders?status=shipped&page=2&limit=20 - Versioning:
/api/v1/...or header-based (Accept: application/vnd.example.v1+json) - Error format (consistent, machine-readable):
{
"error": "validation_error",
"message": "Email is invalid",
"details": {"email": "must be a valid address"},
"traceId": "b1d2-..."
}
Common HTTP Status & Response Codes
- 200 OK – Successful GET/PUT/PATCH/DELETE
- 201 Created – Successful POST that created a resource (include
Locationheader) - 202 Accepted – Request accepted for async processing (e.g., background job)
- 204 No Content – Successful action with no response body (e.g., DELETE)
- 304 Not Modified – Client can use cached version (with ETag)
- 400 Bad Request – Malformed input
- 401 Unauthorized – Missing/invalid credentials
- 403 Forbidden – Authenticated but not allowed
- 404 Not Found – Resource doesn’t exist
- 409 Conflict – Versioning or business conflict
- 415 Unsupported Media Type – Wrong
Content-Type - 422 Unprocessable Entity – Validation failed
- 429 Too Many Requests – Rate limit exceeded
- 500/502/503 – Server or upstream errors
Example: RESTful Calls
Create a customer (POST):
curl -X POST https://api.example.com/v1/customers \
-H "Content-Type: application/json" \
-d '{"email":"ada@example.com","name":"Ada Lovelace"}'
Response (201 Created):
Location: /v1/customers/987
{"id":987,"email":"ada@example.com","name":"Ada Lovelace"}
Update customer (PUT idempotent):
curl -X PUT https://api.example.com/v1/customers/987 \
-H "Content-Type: application/json" \
-d '{"email":"ada@example.com","name":"Ada L."}'
Paginated list (GET):
curl "https://api.example.com/v1/customers?limit=25&page=3"
{
"items": [/* ... */],
"page": 3,
"limit": 25,
"_links": {
"self": {"href": "/v1/customers?limit=25&page=3"},
"next": {"href": "/v1/customers?limit=25&page=4"},
"prev": {"href": "/v1/customers?limit=25&page=2"}
}
}
When Should We Use RESTful?
- Public APIs that need broad adoption (predictable, HTTP-native)
- Microservices communicating over HTTP
- Resource-centric applications (e.g., e-commerce products, tickets, posts)
- Cross-platform needs (web, iOS, Android, IoT)
Benefits
- Simplicity & ubiquity (uses plain HTTP)
- Scalability (stateless + cacheable)
- Loose coupling (uniform interface)
- CDN friendliness and observability with standard tooling
- Language-agnostic (works with any tech stack)
Issues / Pitfalls
- Over/under-fetching (may need GraphQL for complex read patterns)
- N+1 calls from chatty clients (batch endpoints or HTTP/2/3 help)
- Ambiguous semantics if you ignore idempotency/safety rules
- Versioning drift without a clear policy
- HATEOAS underused, reducing discoverability
When to Avoid REST
- Strict transactional workflows needing ACID across service boundaries (consider gRPC within a trusted network or orchestration)
- Streaming/real-time event delivery (WebSockets, SSE, MQTT)
- Heavy RPC semantics across many small operations (gRPC may be more efficient)
- Enterprise contracts requiring formal schemas and WS-* features (SOAP may still fit legacy ecosystems)
Why Prefer REST over SOAP and RPC?
- Human-readable & simpler than SOAP’s XML envelopes and WS-* stack
- Native HTTP semantics (status codes, caching, content negotiation)
- Lower ceremony than RPC (no strict interface stubs required)
- Web-scale proven (born from the web’s architecture per Fielding)
(That said, SOAP can be right for legacy enterprise integrations; gRPC/RPC can excel for internal, low-latency service-to-service calls.)
Is REST Secure? How Do We Make It Secure?
REST can be very secure when you apply standard web security practices:
- Transport Security
- Enforce HTTPS (TLS), HSTS, and strong cipher suites.
- Authentication & Authorization
- OAuth 2.0 / OIDC for user auth (PKCE for public clients).
- JWT access tokens with short TTLs; rotate refresh tokens.
- API keys for server-to-server (limit scope, rotate, never in client apps).
- Least privilege with scopes/roles.
- Request Validation & Hardening
- Validate and sanitize all inputs (size limits, types, patterns).
- Enforce idempotency keys for POSTs that must be idempotent (payments).
- Set CORS policies appropriately (only trusted origins).
- Use rate limiting, WAF, and bot protection.
- Employ ETag + If-Match for optimistic concurrency control.
- Data Protection
- Avoid sensitive data in URLs; prefer headers/body.
- Encrypt secrets at rest; separate KMS for key management.
- Mask/redact PII in logs.
- Headers & Best Practices
Content-Security-Policy,X-Content-Type-Options: nosniff,X-Frame-Options: DENY,Referrer-Policy.- Disable directory listings; correct
Content-Typeon all responses.
- Operational Security
- Centralized logging/trace IDs; audit auth events.
- Zero-trust network segmentation; mTLS inside the mesh where appropriate.
- Regular penetration tests and dependency scanning.
Quick REST Design Checklist
- Clear resource model and URL scheme
- Consistent JSON shapes and error envelopes
- Proper status codes +
Locationon creates - Pagination, filtering, sorting, and sparse-fieldsets
- Idempotent PUT/DELETE; consider idempotency keys for POST
- ETags and cache headers for read endpoints
- Versioning strategy (path or media type)
- OpenAPI/Swagger docs and examples
- AuthZ scopes, rate limits, and monitoring in place
Final Thoughts
REST isn’t a silver bullet, but when you follow Fielding’s constraints—statelessness, cacheability, uniform interface, and layered design—you get services that scale, evolve, and integrate cleanly. Use REST where its strengths align with your needs; reach for SOAP, gRPC, GraphQL, WebSockets, or event streams where they fit better.












Recent Comments