Day7

Client-Server Model

The Client-Server Model is the foundational architecture of the modern internet. It is a distributed application structure that partitions tasks or workloads between the providers of a resource or service, called servers, and service requesters, called clients.


1. The Core Components


A. The Client


The client is the end-user gateway. It does not host the primary data or application logic; instead, it requests it.

  • Examples: A web browser (Chrome, Safari), a mobile app (Instagram, Spotify), or a command-line tool (cURL).

  • Role: Formats user actions into requests, sends them over a network, and renders the server's response into a user-friendly interface.


B. The Server


The server is a centralized machine (or cluster of machines) that is always on, waiting for incoming requests.

  • Examples: An Express.js backend, an AWS EC2 instance, or a cloud database.

  • Role: Listens on a specific network port, validates credentials, processes business logic, queries databases, and sends back the requested data.


C. The Network (The Request-Response Cycle)


Clients and servers communicate over a computer network (like the internet) using established protocols (like HTTP, HTTPS, or WebSockets).

  1. The Request: The client sends an explicit message (e.g., GET /profile).

  2. The Processing: The server receives the message, executes code, and fetches data.

  3. The Response: The server sends data back (e.g., a status code 200 OK along with a JSON payload or HTML file).


2. Key Characteristics


  • Centralized Control: All resources, security permissions, and data access are managed on the server side. If you need to fix a bug or update data, you update the server, and every client instantly gets the new version.

  • Asymmetry: The relationship is uneven. The client always initiates the communication. The server cannot spontaneously send data to a standard client without being asked first (unless modern persistent protocols like WebSockets are implemented).

  • Decoupling: The client doesn't need to know how the server's database works; it only needs to know the API endpoint. The server doesn't care if the client is an iPhone or a Windows laptop, as long as the request is formatted correctly.


3. Client-Server vs. Peer-to-Peer (P2P)


In a P2P network, there is no central server. Each device (peer) can both request and provide resources.


How it works:

  1.  A peer requests a file or resource.
  2. Other peers that have it send it directly.
  3. Multiple peers can share simultaneously.

When moving into system design, it helps to contrast this model with its primary alternative:


FeatureClient-Server ModelPeer-to-Peer (P2P) Model
ArchitectureCentralizedDecentralized
NodesDistinct roles (Client requests, Server serves)Every node acts as both a client and a server
ScalingScaled by upgrading servers (Vertical/Horizontal)Scaled automatically as more peers join the network
ExamplesNetflix, Google, standard web appsBitTorrent, Blockchain networks

4. Evolution of the Model (Tiers)


As systems grow from simple scripts to enterprise platforms, the server side is broken down into "Tiers" to handle scale:


A. 2-Tier Architecture


The client talks directly to the database.

  • Verdict: Fine for simple local software, but terrible for web security because exposing database credentials to the client is a massive risk.


B. 3-Tier Architecture (The Industry Standard)


The structure used in almost every production application, including standard MERN stacks:

  1. Presentation Tier (Client): The UI layer (React, HTML/CSS).

  2. Application Tier (Server): The business logic (Node.js/Express backend).

  3. Data Tier (Database): The storage layer (MongoDB, PostgreSQL).


5. Designing for System Scale


To prevent the server from crashing, you introduce system components we discussed earlier:

  • Load Balancers to distribute the client requests across a pool of application servers.

  • Caches (like Redis) so the application tier doesn't choke the data tier with repetitive queries.

  • Content Delivery Networks (CDNs) to cache static assets (images, frontend code) physically closer to the client, taking the load off your primary servers entirely.


APIs and REST

An API (Application Programming Interface) acts as a formal contract between the client and the server. It specifies exactly what endpoints exist, what data formats are accepted, and what responses to expect, abstracting away the complex database and business logic happening behind the scenes.


While there are many styles of APIs (like GraphQL or gRPC), REST (Representational State Transfer) remains the structural standard for web services.


1. The Core Architectural Constraints of REST


To be considered truly "RESTful," an API must adhere to specific design principles:


A. Statelessness


This is the most critical constraint for system design scalability. Stateless means the server does not store any session context about the client. * Every single HTTP request must be a self-contained unit carrying all the information necessary to understand and process it (e.g., passing a JWT in the Authorization header on every request).

  • Why it matters: If Server A crashes midway through a user session, Server B can handle the very next request instantly because it doesn't rely on local server-side memory. This makes horizontal scaling behind a load balancer trivial.


B. Client-Server Architecture


The user interface (client) and the data storage (server) are completely decoupled. You can rewrite your frontend in Vue, React, or build a native iOS app, and as long as the API contract doesn't change, the backend requires zero modifications.


C. Uniform Interface

Resources are exposed through predictable, standardized paths (URLs) combined with standard HTTP verbs.


2. Resource-Oriented URLs + HTTP Verbs


In a REST API, your URLs should represent nouns (resources), never verbs (actions). You use the HTTP methods we discussed earlier to dictate the action.

The Anti-Pattern vs. The REST Pattern

  • Bad (RPC-style): POST /deleteUser or GET /get_all_active_products

  • Good (RESTful): DELETE /users/:id or GET /products?status=active


Standard CRUD Mapping

ActionHTTP VerbEndpoint (URL)Success Code
Create a new postPOST/posts201 Created
Read all postsGET/posts200 OK
Read a specific postGET/posts/42200 OK
Update a post fullyPUT/posts/42200 OK
Delete a postDELETE/posts/42200 OK (or 204)

3. Data Format: JSON Standard


While REST theoretically supports XML, HTML, or plain text, JSON (JavaScript Object Notation) is the undisputed standard data format for modern web APIs.

  • Lightweight: It has a highly compressed footprint compared to XML, parsing faster and using less bandwidth.

  • Native compatibility: It maps directly to JavaScript objects (perfect for Node.js backends and browser frontends) and is natively supported by almost every programming language.


4. REST vs. GraphQL (The Alternative)


When designing highly complex systems, REST's rigid structural simplicity can sometimes introduce data bottlenecks, leading teams to evaluate GraphQL:


ChallengeREST SolutionGraphQL Solution
Over-fetching (Getting more data than needed)Fixed endpoints return the entire user object, even if you only need the username.The client writes a query specifying exactly what fields it wants.
Under-fetching (Making multiple calls)To show a dashboard, you might have to hit /user, then /orders, then /notifications.The client fetches all nested data in a single request.
CachingExcellent. Natively utilizes standard HTTP cache headers at the proxy layer.Difficult. Usually uses a single POST /graphql endpoint, making network caching hard.

5. System Design Takeaway: Idempotency Keys


Because REST is stateless and networks drop packets, a client might send a POST /payments request, the server processes it, but the network cuts out before the client gets the 200 OK response.

If the client retries the request, they could be double-charged because POST is non-idempotent.

To solve this in production architectures, you implement Idempotency Keys:

  1. The client generates a unique UUID and sends it in the header: Idempotency-Key: abc-123.

  2. The server saves that key to a fast database (like Redis) with a short TTL before processing.

  3. If a second request arrives with the exact same key, the server skips execution and simply returns the cached response from the first run.

Day7 in System Designing · basic | System Designing | Careeroza