WEB API's Lesson 9 – REST Architecture | Dataplexa
Web APIs · Lesson 9

REST Architecture

Explore the foundational structure behind every great API and build your first REST endpoint.

Facebook serves 4.95 billion API calls every day. Netflix streams through thousands of microservices. Shopify processes millions of transactions across borders. Every single one follows the same architectural pattern: REST. Not because it is trendy, but because it works at any scale.

Architecture in software development means the high-level design that determines how different pieces fit together. REST architecture defines how web APIs should behave, what URLs should look like, and how servers should respond to different types of requests. It is not a technology or framework — it is a set of principles that makes APIs predictable and scalable.

The acronym REST stands for Representational State Transfer, but that definition helps nobody. Think of it this way: your API represents resources (users, orders, products) and transfers their current state (the data) when clients ask for them. Every resource gets its own URL. Every action uses a specific HTTP method. Every response follows consistent patterns.

Roy Fielding coined the term REST in his doctoral dissertation back in 2000. He was one of the principal authors of HTTP itself, so he understood better than anyone how web protocols actually work. His insight was simple: instead of inventing new ways to communicate over the internet, why not use HTTP the way it was designed to be used?

The APIForge Challenge
The APIForge Backend team is building their developer platform API from scratch. They need to decide on an architectural approach that will scale from hundreds to millions of developers. REST architecture provides the foundation they need — but first, they need to understand what makes an API truly RESTful.

What REST Architecture Actually Means

Before REST, web services were a mess of competing standards and complex protocols. SOAP required XML schemas longer than entire applications. RPC systems forced you to think in terms of remote function calls rather than web resources. Developers spent more time fighting integration than building features.

REST changed everything by treating the web like the web. Instead of pretending HTTP was just a transport layer, REST embraces HTTP as an application protocol. Resources become URLs. Actions become HTTP methods. State becomes response data. Errors become status codes.

A resource in REST terminology is any piece of information your API can provide. Users are resources. Blog posts are resources. Shopping cart items are resources. The current weather in Tokyo is a resource. Each resource gets identified by a unique URL, called a resource identifier.

The key insight is that REST APIs expose resources, not operations. Instead of endpoints like /getUserById or /deleteUser, you get clean resource paths like /users/123. The HTTP method tells you what action to take.

Concept
Architectural Pattern
Used for
Specification
Industry Status
REST provides a uniform interface for web APIs by mapping business resources to HTTP methods and URLs, creating predictable patterns that scale from prototype to production.

The Resource-Method Matrix

The magic of REST happens when you combine resources with HTTP methods. Every API operation becomes a combination of "which resource" and "what action." This creates a predictable pattern that developers can understand instantly.

Think of resources as nouns and HTTP methods as verbs. GET retrieves. POST creates. PUT updates. DELETE removes. This noun-verb combination eliminates guesswork about what an endpoint does. GET /users/456 obviously retrieves user 456. DELETE /orders/789 obviously removes order 789.

Collections and individual items follow consistent patterns too. /users represents all users. /users/123 represents one specific user. POST to the collection creates a new item. GET from the collection retrieves the list. PUT to an individual item updates it.

Method + Resource What it does APIForge use case
GET /developers List all developers Platform admin sees registered developers
GET /developers/123 Get specific developer Show developer profile and API usage
POST /developers Create new developer Developer signs up for platform account
PUT /developers/123 Update specific developer Developer updates profile or billing info
DELETE /developers/123 Remove specific developer Developer cancels account permanently
GET /developers/123/projects List projects for developer Dashboard shows all developer's projects
Notice how the URLs form a hierarchy. /developers/123/projects means "projects that belong to developer 123." This creates intuitive relationships between resources that mirror real-world connections.

Statelessness in Practice

REST demands that every request contains everything the server needs to process it. No session memory. No conversation history. Each request stands alone, carrying its own authentication, parameters, and context.

This sounds limiting until you realize what it enables. Servers can handle millions of requests without remembering anything about previous ones. Load balancers can route requests to any available server. Caches can store responses without worrying about user state. Systems can scale horizontally by adding more servers.

Statelessness means your API calls look more verbose but behave more predictably. Instead of logging in once and staying authenticated, each request includes an API key or token. Instead of building up context over multiple calls, each request specifies exactly what it wants.

# APIForge developer retrieves their project list
# Every request includes authentication and full context

GET /developers/456/projects HTTP/1.1
Host: api.apiforge.dev
Authorization: Bearer abc123def456ghi789
Accept: application/json
User-Agent: APIForge-Client/2.1.4
HTTP/1.1 200 OK Content-Type: application/json Content-Length: 342 Cache-Control: private, max-age=300 { "projects": [ { "id": "proj_89012", "name": "Mobile Banking API", "status": "active", "created_at": "2024-01-15T10:30:00Z", "api_calls_month": 45600 } ], "total": 1, "developer_id": "456" }
What just happened?
The request included everything needed: authentication token, exact resource path, and response format preference. The server processed it without checking any session storage or user context from previous requests. The response is complete and self-contained. Try this: Notice how the response includes the developer_id even though it was in the URL — REST responses should be understandable on their own.

Uniform Interface Benefits

The uniform interface constraint is what makes REST APIs learnable. Once you understand one well-designed REST API, you can navigate any other REST API with minimal documentation.

Developers expect GET to be safe and idempotent — calling it multiple times produces the same result with no side effects. They expect POST to create resources and return 201 Created on success. They expect DELETE to remove resources and return 204 No Content.

This consistency reduces cognitive load. Developers don't need to memorize custom conventions for every API they integrate. Error handling follows HTTP status code patterns. Authentication uses standard header formats. Response structures follow predictable JSON conventions.

GitHub's API exemplifies uniform interface design. Whether you are managing repositories, issues, or pull requests, the patterns stay consistent. GET /repos/owner/name gets repository details. GET /repos/owner/name/issues gets issues for that repository. POST /repos/owner/name/issues creates a new issue.
# APIForge API follows uniform interface patterns
# Creating a new API key follows standard REST conventions

POST /developers/456/api-keys HTTP/1.1
Host: api.apiforge.dev
Authorization: Bearer abc123def456ghi789
Content-Type: application/json

{
  "name": "Production Mobile App",
  "permissions": ["projects:read", "usage:read"],
  "expires_at": "2025-01-15T00:00:00Z"
}
HTTP/1.1 201 Created Content-Type: application/json Location: /developers/456/api-keys/key_xyz789 Content-Length: 198 { "id": "key_xyz789", "name": "Production Mobile App", "key": "apk_live_123456789abcdef", "permissions": ["projects:read", "usage:read"], "created_at": "2024-02-20T14:30:00Z", "expires_at": "2025-01-15T00:00:00Z" }
What just happened?
The API followed REST conventions perfectly: POST to create a resource, 201 status for successful creation, Location header pointing to the new resource, and a complete representation in the response body. The URL structure /developers/456/api-keys shows the hierarchical relationship between developers and their API keys. Try this: Check how the response includes both the public key ID and the actual secret key value — this is the only time the secret gets returned.

Layered Architecture Advantages

REST systems work through layers, and each layer only knows about the layers immediately next to it. Your client talks to a load balancer. The load balancer talks to application servers. Application servers talk to databases. Nobody needs to understand the entire system.

This layered approach enables powerful optimizations. CDNs cache responses at the edge. Reverse proxies handle SSL termination. Application servers focus on business logic. Database servers handle data persistence. Each layer optimizes for its specific purpose.

Stripe processes hundreds of thousands of payments per minute through layered REST architecture. API requests hit their edge servers first, which handle authentication and basic validation. Approved requests flow to application servers that process business logic. Database operations happen on specialized storage layers. Error responses can come from any layer, but they all follow the same REST patterns.

Real-World Impact
Netflix operates over 700 microservices behind their REST APIs. Each service handles one specific domain like user preferences, content recommendations, or video streaming. The uniform interface lets services communicate without knowing implementation details. When they need to replace a service, they just match the REST interface.

Cache-Friendly Design

REST embraces HTTP caching mechanisms that can dramatically improve performance. Cache-Control headers tell clients and intermediaries how long responses stay valid. ETags enable conditional requests that save bandwidth. Proper caching can reduce API calls by 60% or more.

GET requests should always be cacheable unless they contain sensitive data. Resource representations with stable URLs cache better than dynamic ones. Timestamps and version numbers in responses help clients understand when data changes.

The APIForge team needs to balance data freshness with performance. Developer profile information changes rarely and can cache for hours. API usage statistics change frequently and cache for minutes. Real-time alerts never cache.

# APIForge serves cached developer profile data
# Cache headers optimize for both freshness and performance

GET /developers/456 HTTP/1.1
Host: api.apiforge.dev
Authorization: Bearer abc123def456ghi789
If-None-Match: "dev456-v23"
HTTP/1.1 304 Not Modified ETag: "dev456-v23" Cache-Control: private, max-age=3600 Last-Modified: Tue, 20 Feb 2024 09:15:00 GMT Content-Length: 0
What just happened?
The client sent an If-None-Match header with the ETag from its cached copy. The server compared this against the current resource version and found no changes, so it returned 304 Not Modified with no body content. This saved bandwidth and server processing while keeping the client's cache fresh. Try this: Notice how the server still sends cache headers even in a 304 response — this helps clients understand caching rules.

HATEOAS and Discoverability

HATEOAS stands for Hypermedia as the Engine of Application State, which sounds intimidating but describes something simple: APIs should include links to related resources and available actions.

Instead of requiring clients to construct URLs manually, well-designed REST APIs provide navigation links in responses. If a developer has projects, the developer resource includes links to those projects. If a project can be deleted, the project resource includes a delete link with the proper URL and method.

Few APIs implement full HATEOAS because it adds complexity, but the principle still guides good design. Resource relationships should be discoverable. Available actions should be obvious. URL construction should follow predictable patterns so clients can navigate without hardcoding paths.

Design Tradeoff
Full HATEOAS makes APIs more discoverable but responses larger and more complex. Most successful APIs find a middle ground: consistent URL patterns, resource relationship hints, and standard link conventions like pagination next/prev URLs.
The key insight from REST architecture is that web APIs work best when they embrace HTTP instead of fighting it. Resources map to URLs. Actions map to methods. Responses use standard status codes. Caching follows HTTP rules. This alignment with web standards creates APIs that integrate smoothly with existing web infrastructure. Twilio's API demonstrates REST architecture principles in production. Every resource has a predictable URL structure. Phone numbers, messages, and calls all follow the same patterns. HTTP methods map to actions consistently. Status codes indicate success or failure types. Responses include enough context for clients to understand what happened. The APIForge Backend team now understands that REST architecture isn't about following rules for the sake of rules. It's about building APIs that scale effortlessly, integrate smoothly, and remain maintainable as systems grow. REST provides the foundation, but implementation details matter just as much as architectural principles.

Quiz

1. The APIForge Backend team needs to implement stateless requests. What does this requirement mean for their API design?

2. APIForge wants to create a new project for developer ID 123. Which REST endpoint follows proper resource-method conventions?

3. What advantage does REST's layered architecture provide for the APIForge platform as it scales?

Up Next
REST Principles
APIForge Backend team dives deeper into the six core constraints that make REST APIs scalable and maintainable.