What is REST
REST is not a protocol, library, framework, or RFC specification. It is a cohesive set of architectural principles and constraints. An API or web service that adheres to these c...
🟢 Junior Level
REST (Representational State Transfer) is an architectural style for designing distributed hypermedia systems, formulated by Roy Fielding in his 2000 doctoral dissertation (“Architectural Styles and the Design of Network-based Software Architectures”).
REST is not a protocol, library, framework, or RFC specification. It is a cohesive set of architectural principles and constraints. An API or web service that adheres to these constraints is called RESTful.
Core Architectural Concepts
- Resource: Any conceptual entity that can be named, addressed, and manipulated (e.g., a
User,Order, orPayment). Every resource has at least one unique identifier: a URI (Uniform Resource Identifier), such as/api/v1/orders/42. - Representation: The serialized state of a resource exchanged between client and server at any given point in time (commonly JSON, and less frequently XML, Protocol Buffers, or YAML).
- Standard HTTP Methods: Operations on resources are expressed via standard HTTP verbs:
GET— Reads a resource representation (Safe and Idempotent).POST— Creates a subordinate resource or triggers an action (Neither Safe nor Idempotent).PUT— Replaces an entire target resource with the uploaded payload (Idempotent).PATCH— Applies partial modifications to a resource (Generally non-idempotent, though can be designed idempotently).DELETE— Removes a target resource (Idempotent).
- Standard HTTP Status Codes: The server communicates the execution outcome using standard three-digit codes:
200 OK,201 Created,204 No Content301 Moved Permanently,304 Not Modified400 Bad Request,401 Unauthorized,403 Forbidden,404 Not Found,409 Conflict,422 Unprocessable Content500 Internal Server Error,502 Bad Gateway,503 Service Unavailable
Idiomatic Spring Boot 3 REST Controller
package com.example.controller;
import com.example.dto.CreateUserRequest;
import com.example.dto.UserResponseDto;
import com.example.service.UserService;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.util.List;
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
// GET /api/v1/users - Retrieve collection of resources
@GetMapping
public List<UserResponseDto> getAllUsers() {
return userService.findAll();
}
// GET /api/v1/users/{id} - Retrieve a specific resource
@GetMapping("/{id}")
public ResponseEntity<UserResponseDto> getUserById(@PathVariable Long id) {
return ResponseEntity.ok(userService.findById(id));
}
// POST /api/v1/users - Create a new subordinate resource
@PostMapping
public ResponseEntity<UserResponseDto> createUser(
@Valid @RequestBody CreateUserRequest request,
UriComponentsBuilder ucb) {
UserResponseDto created = userService.create(request);
URI location = ucb.path("/api/v1/users/{id}").buildAndExpand(created.id()).toUri();
return ResponseEntity.created(location).body(created); // 201 Created with Location header
}
// DELETE /api/v1/users/{id} - Remove resource
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT) // 204 No Content
public void deleteUser(@PathVariable Long id) {
userService.deleteById(id);
}
}
🟡 Middle Level
The 6 Architectural Constraints of REST
To be considered strictly RESTful, an architecture must satisfy six core constraints:
┌────────────────────────────────────────────────────────────────────────┐
│ THE 6 REST CONSTRAINTS │
└───────────────────────────────────┬────────────────────────────────────┘
│
┌──────────────┬────────────────┼──────────────┬─────────────────────┐
▼ ▼ ▼ ▼ ▼
Client-Server Stateless Cacheable Layered System Uniform Interface
Separation of No session Explicit TTL Intermediaries 4 Sub-Constraints:
UI and state state stored (ETag / (CDN, Gateway) 1. Resource Ident.
storage on server Cache-Control) are transparent 2. Repr. Manipulation
3. Self-descriptive
4. HATEOAS
│
Code on Demand
(Optional: scripts)
- Client-Server Architecture:
- Strict separation of concerns: User interface and presentation concerns belong to the client; data storage, business transactions, and security belong to the server.
- Allows clients (iOS, Android, React, CLI) and backends to evolve, deploy, and scale independently.
- Stateless:
- The server must not store any client session context between requests.
- Every individual request from a client must contain all the context, identity, and authorization tokens (e.g., Bearer JWT in the
Authorizationheader) necessary to process the request. - Improves scalability dramatically: any available server instance in a cluster can handle any request without shared session state or sticky sessions.
- Cacheable:
- Every response must explicitly label itself as cacheable or non-cacheable (via HTTP response headers such as
Cache-Control,ETag,Last-Modified, andExpires). - Clients and intermediary proxy caches can reuse valid cached representations, eliminating redundant server execution and reducing network latency.
- Every response must explicitly label itself as cacheable or non-cacheable (via HTTP response headers such as
- Layered System:
- A client cannot tell whether it is connected directly to the end application server or to an intermediary layer.
- Intermediary proxies, reverse proxies, API gateways, and CDNs can be introduced to implement load balancing, TLS termination, rate limiting, and shared caching without altering the client-server interaction contract.
- Uniform Interface:
- The cornerstone architectural constraint distinguishing REST from traditional RPC (Remote Procedure Call) patterns. It encompasses four constituent sub-rules:
- Identification of Resources: Discrete resources are identified via uniform identifiers (URIs) separate from their representation format (
/api/v1/accounts/123). - Manipulation of Resources through Representations: When a client holds a representation of a resource (including metadata), it possesses sufficient information to modify or delete that resource state on the server.
- Self-Descriptive Messages: Every message contains enough metadata for the receiver to parse and handle it. Headers like
Content-Type: application/jsondeclare parsing rules, while cache headers define lifespan. - HATEOAS (Hypermedia As The Engine Of Application State): The server delivers dynamic hypermedia links (
_links) alongside data representations, enabling clients to discover next available state transitions without hardcoding URLs.
- Identification of Resources: Discrete resources are identified via uniform identifiers (URIs) separate from their representation format (
- The cornerstone architectural constraint distinguishing REST from traditional RPC (Remote Procedure Call) patterns. It encompasses four constituent sub-rules:
- Code on Demand (Optional):
- The only optional constraint in Fielding’s model.
- A server can temporarily extend or customize client functionality by transferring executable code (e.g., compiled JavaScript, WebAssembly applets).
The Richardson Maturity Model (RMM)
Leonard Richardson established a 4-tier model assessing the degree of REST adherence in web APIs:
Level 3: HATEOAS (Hypermedia Controls)
Responses contain discoverable hyperlinks driving state transitions.
▲
Level 2: HTTP Verbs & Status Codes (Pragmatic REST / Industry Standard)
Semantic usage of GET, POST, PUT, DELETE, and correct HTTP status codes.
▲
Level 1: Resources (Discrete URIs)
Individual URIs for individual domain entities (/users, /orders/42).
▲
Level 0: The Swamp of POX (Plain Old XML / RPC over HTTP)
Single endpoint (e.g., /api/service), POST only, verb encoded in body.
- Level 0 (The Swamp of POX): HTTP is merely utilized as a raw tunneling transport mechanism (e.g., SOAP, XML-RPC, or JSON-RPC). All requests hit a single URL via
POSTwith the method name embedded in the envelope payload. - Level 1 (Resources): Introduces unique URI endpoints for distinct entities (
/users/1,/orders), but operations might still use a single HTTP verb (e.g.,POST /users/1/delete). - Level 2 (HTTP Verbs & Status Codes): Employs standard HTTP method semantics (
GETto fetch,POSTto create,PUTto overwrite,DELETEto erase) and utilizes proper HTTP status codes (200,201,204,400,404). Over 95% of commercial production “REST APIs” reside here. - Level 3 (HATEOAS): True hypermedia-driven architecture. Responses include navigable links (
relattributes) guiding the client through permissible business workflows.
🔴 Senior Level
REST Architectural Trade-offs: When REST is the Wrong Choice
In modern enterprise architectures, REST over JSON/HTTP 1.1 is frequently chosen by default despite notable architectural limitations:
| Protocol / Style | Where It Outperforms REST | Production Decision Criteria |
|---|---|---|
| gRPC (Protocol Buffers over HTTP/2 & HTTP/3) | High-throughput East-West (service-to-service) IPC. Binary serialization is $5\times\text{–}10\times$ faster than JSON parsing; bidirectional streaming; multiplexed connections; compile-time schema enforcement. | Microservice backplanes where sub-millisecond p99 latency, strict schema codegen, and CPU/network efficiency are critical. |
| GraphQL | Solves Over-fetching (retrieving 50 database columns when the UI only renders 2) and Under-fetching (N+1 HTTP calls across multiple endpoints to render one screen). | Mobile client apps, frontend-for-backend (BFF) layers, and rich dashboards aggregating varied domain aggregates. |
| WebSockets / RSocket | Full-duplex, persistent TCP connections with framing overhead measured in bytes rather than kilobytes of HTTP headers per message. | Real-time chat, telemetry, financial order books, live collaborative editing, and high-frequency push events. |
Standardized Error Handling: RFC 9457 (Problem Details)
Before Spring Framework 6 and Spring Boot 3, REST error representations were ad-hoc, proprietary JSON blobs. Spring Boot 3 standardized on RFC 9457 (Problem Details for HTTP APIs):
package com.example.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import java.net.URI;
import java.time.Instant;
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ProblemDetail handleUserNotFound(UserNotFoundException ex) {
ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(
HttpStatus.NOT_FOUND,
ex.getMessage()
);
problemDetail.setTitle("User Resource Not Found");
problemDetail.setType(URI.create("https://api.example.com/errors/user-not-found"));
problemDetail.setProperty("timestamp", Instant.now());
problemDetail.setProperty("errorCode", "USR-404");
return problemDetail;
}
}
Produces an RFC-compliant response (Content-Type: application/problem+json):
{
"type": "https://api.example.com/errors/user-not-found",
"title": "User Resource Not Found",
"status": 404,
"detail": "User with id 42 does not exist",
"instance": "/api/v1/users/42",
"timestamp": "2026-09-27T08:00:00Z",
"errorCode": "USR-404"
}
High-Throughput REST Optimizations in Java 21+
- Virtual Threads (Project Loom):
- Setting
spring.threads.virtual.enabled=trueswitches Tomcat/Jetty dispatching to Virtual Threads (java.lang.VirtualThread). - The thread-per-request blocking model executes blocking I/O (JDBC queries, Redis calls, HTTP outbound clients) without unmounting OS carrier threads.
- Eliminates the need to migrate standard CRUD applications to reactive Spring WebFlux solely to sustain $50{,}000+$ concurrent I/O connections.
- Setting
- HTTP Conditional Caching with
ETag:- Spring MVC’s
ShallowEtagHeaderFiltercalculates an MD5 digest of the response body and attaches anETag: "0a8f9b8c..."header. - Subsequent client requests supply
If-None-Match: "0a8f9b8c...". - If unmodified, the server responds with
304 Not Modifiedand an empty body, saving significant egress bandwidth and client deserialization cycles.
- Spring MVC’s
4 Tricky Questions
1. Is REST a protocol, a specification, or a standard?
Answer: REST is none of the above; it is an architectural style—a set of guiding principles and design constraints established in Roy Fielding’s doctoral dissertation.
- HTTP is a protocol governed by IETF RFC specifications (e.g., RFC 9110, RFC 9112).
- REST does not even strictly mandate HTTP (theoretically, it could operate over another transfer protocol supporting hierarchical addressing and representations), though in practice, HTTP is its universal implementation vehicle.
- Because REST is an architectural style rather than a strict binary standard, developers implement pragmatic adaptations (such as Richardson Maturity Level 2) tailored to organizational requirements without violating protocol conformance.
2. What is the Uniform Interface constraint, and what are its four constituent sub-constraints?
Answer: The Uniform Interface is the defining characteristic of REST that decouples client implementations from server resource architectures. It mandates four specific rules:
- Identification of Resources: Individual resources are addressed via stable, canonical URIs independent of representations (
/orders/101). - Manipulation of Resources through Representations: Clients hold representations (e.g., JSON) containing sufficient metadata to modify or delete the underlying resource state via HTTP verbs.
- Self-Descriptive Messages: Every message carries standard metadata (
Content-Type,Content-Length,Cache-Control) instructing the recipient how to parse and handle the payload without out-of-band context. - HATEOAS (Hypermedia As The Engine Of Application State): The server supplies contextual hyperlinks (
_links) in response bodies, guiding the client on permissible next actions (e.g., cancel, pay, or ship an order) dynamically based on current resource state.
3. What is the fundamental technical difference between a RESTful API and a generic HTTP API?
Answer:
- A generic HTTP API treats HTTP merely as a network transport pipe. It frequently operates as an RPC mechanism (Richardson Maturity Level 0 or 1), funneling distinct commands through a single endpoint (e.g.,
POST /api/endpointwith{"action": "deleteUser", "userId": 42}) and returning200 OKeven when business exceptions occur. - A RESTful API adheres to the architectural constraints of REST:
- It exposes domain resources via clean URIs (
DELETE /api/users/42). - It strictly respects standard HTTP semantics (safety, idempotency, and status codes).
- It maintains zero session state on the server (Stateless).
- It leverages standard HTTP infrastructure for caching, intermediaries, and content negotiation (
Accept,Content-Type).
- It exposes domain resources via clean URIs (
4. Why is HATEOAS rarely adopted in commercial production APIs despite being required for true REST (Level 3)?
Answer: While HATEOAS represents the purest vision of REST, its commercial adoption is minimal due to several engineering trade-offs:
- Frontend Coupling vs. Dynamic Discovery: Modern single-page applications (React, Vue, Angular) and mobile clients rely on static UI routing, design systems, and client-side state machines. Dynamic UI rendering driven purely by server-provided hypermedia links adds significant frontend complexity.
- Payload Bloat: Hypermedia link blocks (
_links,_embeddedin HAL or JSON:API formats) substantially increase payload size, consuming egress bandwidth and inflating JSON parsing overhead on low-power mobile devices. - OpenAPI / Swagger Standardization: The industry coalesced around static compile-time contracts (OpenAPI/Swagger specs, TypeScript client generators, and gRPC stubs), which provide typed client generation and compile-time validation that HATEOAS’s dynamic runtime link discovery does not offer.
🎯 Interview Cheat Sheet
30-Second Elevator Pitch
REST is an architectural style for distributed hypermedia systems introduced by Roy Fielding in 2000. It is defined by 6 core constraints: Client-Server, Stateless, Cacheable, Layered System, Uniform Interface (including HATEOAS), and Code on Demand (optional).
In practice, web APIs are categorized by the Richardson Maturity Model:
- Level 0: RPC tunneling over HTTP (POX/SOAP).
- Level 1: Individual Resource URIs.
- Level 2: HTTP Verbs & Status Codes (the pragmatic industry standard).
- Level 3: Full HATEOAS discoverability.
Red Flags (What NOT to Say)
- ❌ “REST is an official protocol standardized by W3C or IETF.” (It is an architectural style from a PhD dissertation, implemented over the HTTP protocol).
- ❌ “GET requests can be used for state mutations as long as they return JSON.” (GET must remain strictly Safe and Idempotent according to RFC 9110).
- ❌ “REST APIs must strictly use JSON.” (REST is agnostic to representation formats; XML, Protobuf, and MessagePack are equally valid representations).
- ❌ “The REST server stores user login sessions in HTTP session memory.” (The Stateless constraint strictly prohibits storing client conversational state on the server).
Related Topics
- What does Stateless mean in REST context — Statelessness constraint mechanics
- What are the main HTTP methods used in REST — Verb semantics, safety, and idempotency
- What is the difference between PUT and PATCH — Complete replacement vs. partial mutation
- What is idempotency — Mathematical and network idempotency definitions
- What is HATEOAS — Richardson Maturity Model Level 3 implementation