🌐 Section 6 · Question #1

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

  1. Resource: Any conceptual entity that can be named, addressed, and manipulated (e.g., a User, Order, or Payment). Every resource has at least one unique identifier: a URI (Uniform Resource Identifier), such as /api/v1/orders/42.
  2. 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).
  3. 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).
  4. Standard HTTP Status Codes: The server communicates the execution outcome using standard three-digit codes:
    • 200 OK, 201 Created, 204 No Content
    • 301 Moved Permanently, 304 Not Modified
    • 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Content
    • 500 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)
  1. 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.
  2. 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 Authorization header) 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.
  3. Cacheable:
    • Every response must explicitly label itself as cacheable or non-cacheable (via HTTP response headers such as Cache-Control, ETag, Last-Modified, and Expires).
    • Clients and intermediary proxy caches can reuse valid cached representations, eliminating redundant server execution and reducing network latency.
  4. 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.
  5. 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/json declare 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.
  6. 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 POST with 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 (GET to fetch, POST to create, PUT to overwrite, DELETE to 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 (rel attributes) 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+

  1. Virtual Threads (Project Loom):
    • Setting spring.threads.virtual.enabled=true switches 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.
  2. HTTP Conditional Caching with ETag:
    • Spring MVC’s ShallowEtagHeaderFilter calculates an MD5 digest of the response body and attaches an ETag: "0a8f9b8c..." header.
    • Subsequent client requests supply If-None-Match: "0a8f9b8c...".
    • If unmodified, the server responds with 304 Not Modified and an empty body, saving significant egress bandwidth and client deserialization cycles.

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:

  1. Identification of Resources: Individual resources are addressed via stable, canonical URIs independent of representations (/orders/101).
  2. 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.
  3. 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.
  4. 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/endpoint with {"action": "deleteUser", "userId": 42}) and returning 200 OK even 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).

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:

  1. 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.
  2. Payload Bloat: Hypermedia link blocks (_links, _embedded in HAL or JSON:API formats) substantially increase payload size, consuming egress bandwidth and inflating JSON parsing overhead on low-power mobile devices.
  3. 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).