Understanding REST: Core Architecture, HTTP Synergy, and Trade-offs

Arpit Bhayani

Arpit Bhayani

May 30, 2022 • 10 min read

Play

Understanding REST: Core Architecture, HTTP Synergy, and Trade-offs

In modern web engineering, the terms REST and HTTP APIs are frequently treated as synonyms. Developers often assume that exposing a JSON-over-HTTP endpoint automatically means they are writing a RESTful service. However, REST (Representational State Transfer) is not a protocol, nor is it strictly tied to HTTP. It is an architectural style and specification for how clients and servers should interact through representations of resources.

Understanding REST requires decoupling the specification from its underlying transport protocol, analyzing why HTTP became its de facto runtime environment, and evaluating the architectural trade-offs inherent in building RESTful systems.


1. The Core Philosophy: Everything is a Resource

At the heart of REST lies a fundamental abstraction: the resource. A resource is any conceptual entity within a domain model that can be identified, named, addressed, and manipulated.

  • In a Library Management System, resources include Student, Book, or BorrowRecord.
  • In an E-commerce Platform, resources include User, Item, Seller, or PurchaseOrder.
  • In a Messaging Platform, resources include Message, Channel, or Participant.
+-------------------------------------------------------------------+
|                           CLIENT LAYER                            |
+-------------------------------------------------------------------+

                 Demands resource representation
             (e.g., Accept: application/json, text/csv)

+-------------------------------------------------------------------+
|                         REST API SERVER                           |
|       - Maps URL to Resource Identification                       |
|       - Translates internal state to requested representation      |
+-------------------------------------------------------------------+

                    Fetches raw persisted data

+-------------------------------------------------------------------+
|                    DATA PERSISTENCE / STORAGE                     |
|  Relational DB (Rows/Cols) | Cassandra (Wide-Column) | Document   |
+-------------------------------------------------------------------+

Decoupling Internal Storage from External Representation

A critical rule of REST is the strict separation between how a resource is persisted internally and how it is represented externally to consumers:

  • Internal Storage: An implementation detail. A Student resource can be stored across three normalized tables in PostgreSQL, or as a document in MongoDB, or as a key-value pair in RocksDB.
  • External Representation: What the client interacts with. The server transforms the underlying persistence model into a standardized format such as JSON, XML, CSV, or plain text.

Because storage and representation are decoupled, client-server evolution can occur independently. A database schema migration (e.g., splitting a table, migrating from MySQL to Cassandra) does not require a breaking API change, provided the external representation remains stable.

Representational State Transfer and Content Negotiation

The phrase State Transfer refers to transferring the snapshot of a resource’s current state in a particular format. Through content negotiation, clients can request different representations of the exact same resource using standard metadata (such as HTTP Accept and Content-Type headers):

  • Accept: application/json \rightarrow Server serializes the resource state into JSON.
  • Accept: text/csv \rightarrow Server serializes the resource state into CSV tabular data.
  • Accept: application/xml \rightarrow Server serializes the resource state into XML nodes.

While supporting multiple representations is not strictly mandatory for every API, the architectural flexibility to transfer state in arbitrary representations is a defining property of REST.


2. REST vs. HTTP: Specification vs. Implementation

REST is an architectural specification, not an implementation. It mandates that communication revolves around resources, identification, and standard actions, but it does not mandate the network transport. In theory, REST could be implemented over raw TCP, SCTP, or custom application protocols.

In practice, HTTP is universally used to implement REST. This alignment occurred because HTTP’s native mechanics naturally mirror RESTful principles.

RESTful Modeling vs. RPC-Style HTTP APIs

Many APIs using HTTP are actually Remote Procedure Calls (RPC) masquerading as REST. The distinction lies in whether the URL targets an action (RPC) or a resource identifier (REST).

FeatureRPC-Style EndpointTrue RESTful Endpoint
Resource IdentificationAction is baked into URL (/getStudent, /deleteUser)URL strictly identifies the resource (/students/1, /users/123)
Action DefinitionSpecified via URL verbs or payload commandsDetermined strictly by standard HTTP methods (GET, POST, DELETE, etc.)
Operation MultiplexingRequires distinct endpoints for every mutationMultiplexes actions against the same URL using HTTP verbs
SemanticsNon-standard; every API defines its own verbsStandardized via HTTP specifications (safe, idempotent methods)
# Non-RESTful (RPC style over HTTP):
POST /getStudentById        Body: { "id": 123 }
POST /updateStudentDetails  Body: { "id": 123, "name": "Alice" }
POST /deleteStudentRecord   Body: { "id": 123 }

# RESTful Equivalent:
GET    /students/123        -> Fetches state of resource 'students/123'
PUT    /students/123        -> Replaces/updates state of resource 'students/123'
DELETE /students/123        -> Destroys resource 'students/123'

3. Why HTTP Gelled Perfectly with REST

HTTP succeeded as the premier REST transport due to two major factors: verb multiplexing and a battle-tested global infrastructure.

1. HTTP Verbs as Standardized Resource Operations

HTTP provides uniform methods out of the box that map directly to resource lifecycle operations:

  • GET: Safe, idempotent retrieval of resource representation.
  • POST: Creation of a subordinate resource or processing state changes.
  • PUT: Idempotent replacement or creation of the target resource.
  • PATCH: Partial modification of resource state.
  • DELETE: Removal of the specified resource.

Because every compliant web server, client library, proxy, and gateway understands these verbs, developers can multiplex operations over the exact same URL without reinventing dispatching mechanisms.

2. Piggybacking on Existing Web Infrastructure

Building a custom protocol requires inventing caching engines, debugging utilities, reverse proxies, and load balancers. By running REST over HTTP, systems inherit a vast ecosystem for free:

  • Client Tooling: Native browser integration, CLI utilities (curl, wget), GUI testing tools (Postman, Insomnia), and mature language libraries (requests in Python, fetch/axios in JavaScript).
  • Intermediary Web Caches: Off-the-shelf reverse proxies like Nginx, Varnish, and HAProxy can inspect HTTP headers (Cache-Control, ETag, Last-Modified) and cache responses at the network boundary without application-level logic.
  • Load Balancers: Layer-7 load balancers distribute traffic based on HTTP paths, methods, or headers out of the box.
  • Observability & Tracing: Distributed tracing systems (OpenTelemetry, Jaeger), packet sniffers (Wireshark), APMs (Datadog, New Relic), and web server access logs parse HTTP natively.
  • Security & Optimization: TLS/SSL termination, HTTP/2 multiplexing, and compression algorithms (Gzip, Brotli) are handled transparently by reverse proxies.

4. The Hidden Downsides of REST over HTTP

Despite its dominance, running REST over HTTP introduces non-trivial architectural trade-offs, particularly for high-throughput, low-latency, or distributed microservice environments.

+---------------------------------------------------------------------+
|                   CHALLENGES OF REST OVER HTTP                      |
+---------------------------------------------------------------------+
|  1. Heavy Serialization  | JSON strings, quotes, and structural     |
|     Overhead             | redundancy inflate network payloads.     |
+--------------------------+------------------------------------------+
|  2. Repetitive Client    | No native stubs; every consumer writes   |
|     Boilerplate          | deserialization, retries, and handling.  |
+--------------------------+------------------------------------------+
|  3. Incomplete Server    | Constrained web servers or firewalls may |
|     Verb Support         | block verbs like PUT, PATCH, or DELETE.  |
+--------------------------+------------------------------------------+
|  4. Protocol Rigidity    | Bound strictly to TCP; cannot switch to  |
|                          | UDP for loss-tolerant, low-latency flows.|
+---------------------------------------------------------------------+

1. High Consumption Friction and Lack of Native Stubs

In RPC frameworks (such as gRPC), an Interface Definition Language (IDL) file (e.g., .proto) compiles into native programming language stubs. In a Python service communicating with a Go service via gRPC, both services consume strongly-typed native objects.

In REST over HTTP:

  • There is no universally enforced schema or stub compiler out of the box.
  • Clients receive raw byte streams (e.g., stringified JSON).
  • Every client must manually parse the JSON into a generic structure (like a Python dictionary or JavaScript object) and then unmarshal it into domain classes.
  • Dynamic parsing and reflection at runtime introduce latency and memory allocation overhead.

2. Repetitive Client-Side Plumbing

Because REST over HTTP lacks built-in orchestration conventions, every consuming application or service must independently implement:

  • Serialization and deserialization pipelines.
  • Timeout management and connection pool tuning.
  • Exponential backoff and retry policies.
  • Error response parsing (differentiating between HTTP-level transport errors and domain-specific error schemas).

Without dedicated, internally maintained Shared Client SDKs, teams constantly duplicate this boilerplate across different services.

3. Payload Bloat (JSON vs. Binary Formats)

JSON is designed for human readability, not wire efficiency. It suffers from inherent redundancy:

  • Repeated field names in every object (e.g., "student_id", "first_name").
  • Syntactical baggage: structural tokens like double quotes, colons, commas, and curly braces.
  • Text-encoded numeric types and timestamps that consume significantly more bytes than raw binary encodings.

For inter-service communication operating at tens of thousands of requests per second, this structural bloat consumes substantial bandwidth and incurs measurable CPU serialization/deserialization penalties. Binary protocols (such as Protocol Buffers) compress payloads into compact, tagged fields, yielding far higher throughput.

4. Restricted HTTP Verb Support in Legacy Environments

Not every infrastructure component or runtime supports the full spectrum of HTTP verbs (PUT, DELETE, PATCH, OPTIONS):

  • Some constrained micro-servers, corporate firewalls, or legacy proxy layers only allow GET and POST.
  • When intermediate proxies strip or drop DELETE or PUT packets, developers are forced to break REST conventions—either by falling back to RPC-style endpoints (/students/1/delete) or using method-override headers (X-HTTP-Method-Override: DELETE), defeating the original elegance of uniform interface modeling.

5. Transport Layer Rigidity (TCP vs. UDP)

HTTP relies strictly on TCP (or QUIC in HTTP/3). TCP enforces ordered delivery and connection establishment through three-way handshakes.

If a service requires an ultra-low-latency, fire-and-forget channel where minor packet loss is acceptable (such as metrics ingestion, real-time gaming state, or high-frequency telemetry streams), switching to UDP is fundamentally impossible while adhering to REST over HTTP. RPC frameworks and custom protocols, in contrast, allow decoupling the communication layer from the underlying transport protocol.


5. Architectural Decision Matrix: REST vs. RPC

Choosing between REST over HTTP and alternative communication paradigms (like RPC/gRPC) depends heavily on the consumer profile and system Service Level Agreements (SLAs):

Architectural VectorREST over HTTPRPC (e.g., gRPC / Protobuf)
Primary Use CasePublic APIs, Web/Mobile Client-to-BackendInternal Microservice-to-Microservice communication
Payload FormatText-heavy (JSON, XML, CSV)Binary (Protocol Buffers, FlatBuffers)
Performance & LatencyModerate (parsing overhead, larger payloads)Ultra-low (binary packing, minimal CPU footprint)
Interface ContractDocumentation-driven (OpenAPI/Swagger)Strict IDL contract (.proto files)
Client GenerationOften manual or loosely generated via OpenAPINative stub compilation across polyglot systems
Intermediary CachingNative across proxies (Nginx, CDNs)Complex; requires application-layer caching
Browser SupportUniversal out of the boxRequires gRPC-Web proxy layers for standard browsers

Key Architectural Takeaways

  1. REST is an architectural style, not a protocol. It governs how resources are identified and how their state representations are transferred between clients and servers.
  2. Storage and representation are independent. Data can be stored in normalized tables or document stores while being exposed externally as JSON, CSV, or XML depending on client demand.
  3. HTTP verbs represent actions; URLs represent resources. A well-designed REST API uses URLs strictly for resource identification (/resource/:id) and multiplexes operations using standard HTTP verbs (GET, POST, PUT, DELETE).
  4. REST over HTTP succeeds due to ecosystem reuse. It inherits battle-tested web caches, load balancers, monitoring tools, and ubiquitous client support without bespoke protocol development.
  5. Evaluate the trade-offs before defaulting. For latency-critical internal service meshes, the JSON parsing overhead, boilerplate consumption code, and TCP rigidity of REST over HTTP often justify choosing binary RPC frameworks instead.
Arpit Bhayani

Principal Engineer II at Razorpay - building Agent Studio, Ex-staff engg at GCP Memorystore & Dataproc, Creator of DiceDB, ex-Amazon Fast Data, ex-Director of Engg. SRE and Data Engineering at Unacademy. I spark engineering curiosity through my no-fluff engineering videos on YouTube and my courses