Skip to content

🌐 Networking in System Design

Understanding networking is the backbone of distributed systems. Let's break down the core protocols, how services communicate, and see a practical architecture example.

1. The Core Transport Protocols

At the fundamental level, when systems talk over a network, they generally use one of two transport protocols.

TCP vs UDP

FeatureTCP (Transmission Control Protocol)UDP (User Datagram Protocol)
ReliabilityHigh (Guarantees delivery, retries lost packets)Low (Fire and forget, drops packets)
ConnectionConnection-oriented (Performs a handshake)Connectionless
SpeedSlower (Overhead from reliability checks)Very Fast
Use CasesWeb/HTTP, Databases, Emails, File TransferVideo Streaming, Gaming, VoIP

TIP

In most system design interviews and software architectures, unless you're building a real-time streaming or gaming service, your default assumption is TCP (often wrapped in HTTP/HTTPS).


2. Application Layer Communication Styles

How do microservices or clients and servers actually talk to each other using those transport protocols?

Mermaid Diagram: API Communication Options

  • REST: The classic standard. Uses standard HTTP verbs (GET, POST, PUT, DELETE). Good for public-facing APIs.
  • GraphQL: Great for mobile clients that need varying shapes of data. Prevents over-fetching and under-fetching.
  • WebSockets: Creates a bi-directional, persistent connection. Used for chat apps, live sports tickers, or real-time dashboards.
  • gRPC: Extremely fast, uses highly compressed binary data (Protocol Buffers). Perfect for server-to-server (internal) communication in microservices.

3. Practical Architecture: API Gateway Pattern

In a modern distributed system, you rarely expose your internal microservices directly to the web. Instead, network traffic flows through an API Gateway, which sits between your clients and your backend.

The API Gateway acts as a reverse proxy, handling routing, SSL termination, authentication, and rate limiting.

System Design Architecture Diagram


4. Code Example: Building a Networking Gateway

Let's look at an easy-to-understand Node.js (Express.js) code example demonstrating this architectural concept.

We will create a simple API Gateway that receives external network requests and routes them to the appropriate underlying microservice (simulated here).

NOTE

This code demonstrates the networking routing aspect from a single external entry point to segregated backend services.

javascript
const express = require("express");
const axios = require("axios"); // Used to make HTTP network calls
const app = express();

const PORT = 3000;

// --- 1. Global Networking Middleware ---
// Let's log the network requests coming in from clients
app.use((req, res, next) => {
  console.log(
    `[Network Log] ${req.method} request to ${req.url} from IP: ${req.ip}`
  );
  // In a real system, you might check an Auth token here before calling next()
  next();
});

// --- 2. API Gateway Routing ---

// Route 1: Forwarding to the User Service
app.get("/api/users/:id", async (req, res) => {
  try {
    const userId = req.params.id;

    // In a real system, the gateway makes a network call over the internal VPC
    // const response = await axios.get(`http://internal-user-service:4000/users/${userId}`);
    // res.status(200).json(response.data);

    // Simulating the backend network response for this example
    const mockBackendResponse = {
      id: userId,
      username: "john_doe",
      role: "admin",
    };

    res.status(200).json({
      source: "API Gateway",
      routedTo: "User Microservice",
      data: mockBackendResponse,
    });
  } catch (error) {
    res
      .status(500)
      .json({ error: "Network communication failed with User Service" });
  }
});

// Route 2: Forwarding to the Order Service
app.get("/api/orders/:id", async (req, res) => {
  try {
    const orderId = req.params.id;

    // The Gateway routes this specific path to the Order Service via HTTP/gRPC
    const mockOrderResponse = {
      orderId: orderId,
      amount: 250,
      status: "shipped",
    };

    res.status(200).json({
      source: "API Gateway",
      routedTo: "Order Microservice",
      data: mockOrderResponse,
    });
  } catch (error) {
    res
      .status(500)
      .json({ error: "Network communication failed with Order Service" });
  }
});

app.listen(PORT, () => {
  console.log(`🚀 API Gateway running on port ${PORT}`);
  console.log(`Test Route 1: http://localhost:${PORT}/api/users/123`);
  console.log(`Test Route 2: http://localhost:${PORT}/api/orders/999`);
});

Why this architectural choice is powerful

  1. Single Entry Point: The client only needs to know one single domain (api.yourcompany.com).
  2. Network Security: The Gateway sits in the public subnet, while the microservices and databases sit in a private subnet hidden from the public internet.
  3. Decoupled Internal Network: You can change where the User Service lives securely in your internal network (e.g., migrating servers) without ever updating the client applications.

Released under the ISC License.