# Day 3: HTTP Module and Building a Basic Server In Node.JS

---

#### **1\. Theory:**

---

#### **Introduction to Networking in Node.js**

* **What is Networking?**
    
    * Networking refers to the communication between a client and a server using network protocols like **HTTP**, **TCP**, **UDP**, etc.
        
* **What is HTTP?**
    
    * **HTTP (HyperText Transfer Protocol)** is a protocol used for transferring data over the web. In Node.js, the `http` module allows you to create an HTTP server to listen for incoming requests and send responses to clients.
        

---

#### **Understanding HTTP Protocols**

* **Request and Response Cycle:**
    
    * The client (browser, Postman, etc.) sends an HTTP request to the server.
        
    * The server processes the request and sends back an HTTP response.
        
* **HTTP Methods:**
    
    * **GET**: Used to retrieve data from the server.
        
    * **POST**: Used to send data to the server.
        
    * **PUT, DELETE**: Other methods used for modifying or deleting data.
        

---

#### **Basics of Creating an HTTP Server in Node.js**

* **Using the** `http` Module:
    
    * The `http` module in Node.js allows you to create a simple web server that can handle incoming HTTP requests and send responses.
        
    * You can handle different **routes** (e.g., `/home`, `/about`) and different **HTTP methods** (e.g., GET, POST) to serve different types of content.
        

---

### **TCP (Transmission Control Protocol):**

* **Strengths**:
    
    * **Reliable**: TCP ensures that all data is delivered in the correct order, with error checking and retransmission of lost packets.
        
    * **Connection-Oriented**: A reliable connection is established between the two endpoints before data transfer begins, ensuring consistency.
        
    * **Use Case in Real-Time Communication**:
        
        * **Chat applications**: Many real-time messaging apps, such as WhatsApp or Facebook Messenger, use TCP because reliability is crucial in text-based communication. Missing or out-of-order messages would disrupt the user experience.
            
        * **VoIP with fallback to TCP**: In cases where network conditions are unreliable, some VoIP systems fall back to TCP for improved reliability.
            
        * **Video conferencing (with TCP fallback)**: Some systems use TCP to ensure delivery, but usually at the cost of higher latency.
            
    
    ```javascript
    const net = require("net");
    const readline = require("readline");
    
    // Create a TCP server
    const server = net.createServer((socket) => {
      console.log("Client connected");
      socket.write("Hello, TCP World!\n");
    
      // Receive data from the client
      socket.on("data", (data) => {
        console.log(`Client says: ${data}`);
        socket.write(`You said: ${data}`); // Echo the message back
      });
    
      // Close the connection
      socket.on("end", () => {
        console.log("Client disconnected");
      });
    
      // Now allow input from the server terminal and send to client
      const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
      });
    
      rl.on("line", (input) => {
        socket.write(`Server says: ${input}\n`);
      });
    });
    
    // Listen on port 4000
    server.listen(4000, () => {
      console.log("TCP server listening on port 4000");
    });
    ```
    

### **UDP (User Datagram Protocol):**

* **Strengths**:
    
    * **Fast and Low Latency**: UDP is faster than TCP because it doesn’t establish a connection or handle packet retransmission, which makes it ideal for real-time communication where speed is more important than reliability.
        
    * **Connectionless**: UDP sends packets without establishing a connection, so it is lightweight and better for real-time, high-speed transmissions.
        
* **Use Case in Real-Time Communication**:
    
    * **Voice over IP (VoIP)**: Applications like Zoom, Skype, or Google Meet often use UDP for transmitting voice data, as low latency is critical, and occasional packet loss is acceptable.
        
    * **Online Gaming**: Many real-time multiplayer games use UDP for transmitting game data, where speed and low latency are prioritized over perfect delivery. Lost packets are usually acceptable because real-time updates happen continuously.
        
    * **Live Streaming**: UDP is used for real-time video and audio streaming because it can handle large amounts of data without waiting for acknowledgment of each packet, reducing latency.
        

### **2\. Practical:**

---

#### **Task 1: Create a Basic HTTP Server**

**What to do:**

* Create a simple Node.js HTTP server using the `http` module that listens on port 3000 and responds with a message.
    

**Example:**

```javascript
const http = require('http');

// Create an HTTP server
const server = http.createServer((req, res) => {
  // Set the response header
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  
  // Send a simple response
  res.end('Hello, World!\n');
});

// The server listens on port 3000
server.listen(3000, () => {
  console.log('Server is listening on port 3000...');
});
```

**Run the server:**

```javascript
node server.js
```

* Open the browser and go to [`http://localhost:3000`](http://localhost:3000), and you will see **"Hello, World!"** displayed.
    

---

#### **Task 2: Responding with Static Content (HTML and JSON)**

**What to do:**

* Modify the server to respond with **HTML content** when the request URL is `/home` and with **JSON data** when the request URL is `/api`.
    

**Example:**

```javascript
const http = require('http');

// Create an HTTP server
const server = http.createServer((req, res) => {
  if (req.url === '/home') {
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end('<h1>Welcome to the Home Page!</h1>');
  } else if (req.url === '/api') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    const data = {
      message: 'Hello, this is JSON data!',
      status: 'success',
    };
    res.end(JSON.stringify(data));
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('404 - Not Found');
  }
});

// The server listens on port 3000
server.listen(3000, () => {
  console.log('Server is listening on port 3000...');
});
```

**Test the server:**

* Go to [`http://localhost:3000/home`](http://localhost:3000/home), and you will see the HTML content.
    
* Go to [`http://localhost:3000/api`](http://localhost:3000/api), and you will receive the JSON response.
    

---

#### **Task 3: Handling Different Routes and HTTP Methods (GET, POST)**

**What to do:**

* Modify the server to handle two different routes:
    
    * `/about`: Responds with a simple HTML message using the GET method.
        
    * `/submit`: Accepts POST requests and responds with the data that the client submits.
        

**Example:**

```javascript
const http = require('http');

// Create an HTTP server
const server = http.createServer((req, res) => {
  if (req.method === 'GET' && req.url === '/about') {
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end('<h1>About Us</h1><p>This is the about page.</p>');
  } else if (req.method === 'POST' && req.url === '/submit') {
    let body = '';

    // Collect the data sent by the client
    req.on('data', chunk => {
      body += chunk.toString();
    });

    // Once all data is received, respond with it
    req.on('end', () => {
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end(`Received data: ${body}`);
    });
  } else {
    res.writeHead(404, { 'Content-Type': 'text/plain' });
    res.end('404 - Not Found');
  }
});

// The server listens on port 3000
server.listen(3000, () => {
  console.log('Server is listening on port 3000...');
});
```

**Test the server:**

* Visit [`http://localhost:3000/about`](http://localhost:3000/about) to see the **GET** request in action.
    
* Use Postman or `curl` to send a **POST** request with data to [`http://localhost:3000/submit`](http://localhost:3000/submit).
    

Example using `curl`:

```javascript
curl -X POST -d "name=John&age=25" http://localhost:3000/submit
```

**Output:**

```javascript
Received data: name=John&age=25
```

---

### **3\. Extended Practical Examples:**

#### **Task 4: Serve a Static HTML File**

**What to do:**

* Create an **HTML file** (e.g., `index.html`) and serve it using the `fs` module with the HTTP server.
    

**Example:**

1. Create an `index.html` file:
    
    ```xml
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Portfolio</title>
        <style>
          * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
          }
          body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            background-color: #f4f4f4;
            color: #333;
          }
          header {
            background-color: #333;
            color: #fff;
            padding: 1rem 0;
            text-align: center;
          }
          header h1 {
            margin-bottom: 0.5rem;
          }
          header p {
            font-size: 1.1rem;
          }
          nav {
            background-color: #444;
            padding: 1rem;
            text-align: center;
          }
          nav a {
            color: #fff;
            margin: 0 15px;
            text-decoration: none;
            font-weight: bold;
          }
          nav a:hover {
            text-decoration: underline;
          }
          .container {
            max-width: 1100px;
            margin: 2rem auto;
            padding: 0 2rem;
          }
          .about,
          .projects {
            background-color: #fff;
            padding: 2rem;
            margin-bottom: 1.5rem;
            border-radius: 5px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
          }
          .about h2,
          .projects h2 {
            margin-bottom: 1rem;
          }
          .about p {
            font-size: 1.1rem;
            line-height: 1.8;
          }
          .projects {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 1.5rem;
          }
          .project-card {
            background-color: #f9f9f9;
            padding: 1.5rem;
            border-radius: 5px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
          }
          .project-card h3 {
            margin-bottom: 0.5rem;
          }
          .project-card p {
            margin-bottom: 1rem;
          }
          footer {
            background-color: #333;
            color: #fff;
            text-align: center;
            padding: 1rem 0;
          }
          footer p {
            margin: 0;
          }
        </style>
      </head>
      <body>
        <header>
          <h1>Sungava College</h1>
          <p>Web Developer | Designer | Programmer</p>
        </header>
    
        <nav>
          <a href="#about">About</a>
          <a href="#projects">Projects</a>
          <a href="#contact">Contact</a>
        </nav>
    
        <div class="container">
          <section id="about" class="about">
            <h2>About Me</h2>
            <p>
              Hello! I'm Apple, a passionate web developer with experience in
              building dynamic and responsive websites. I enjoy turning complex
              problems into simple, beautiful, and intuitive solutions.
            </p>
          </section>
    
          <section id="projects" class="projects">
            <h2>Projects</h2>
            <div class="project-card">
              <h3>Project One</h3>
              <p>A responsive website built with HTML, CSS, and JavaScript.</p>
              <a href="#">View Project</a>
            </div>
            <div class="project-card">
              <h3>Project Two</h3>
              <p>A dynamic web application using the MERN stack.</p>
              <a href="#">View Project</a>
            </div>
            <div class="project-card">
              <h3>Project Three</h3>
              <p>An eCommerce platform built using React and Node.js.</p>
              <a href="#">View Project</a>
            </div>
          </section>
        </div>
    
        <footer>
          <p>&copy; 2024 Sungava College. All Rights Reserved.</p>
        </footer>
      </body>
    </html>
    ```
    
2. Modify the server to read and serve this file:
    
    ```javascript
    const http = require('http');
    const fs = require('fs');
    
    // Create an HTTP server
    const server = http.createServer((req, res) => {
      if (req.url === '/home') {
        fs.readFile('index.html', (err, data) => {
          if (err) {
            res.writeHead(500, { 'Content-Type': 'text/plain' });
            res.end('500 - Internal Server Error');
          } else {
            res.writeHead(200, { 'Content-Type': 'text/html' });
            res.end(data);
          }
        });
      } else {
        res.writeHead(404, { 'Content-Type': 'text/plain' });
        res.end('404 - Not Found');
      }
    });
    
    // The server listens on port 3000
    server.listen(3000, () => {
      console.log('Server is listening on port 3000...');
    });
    ```
    

**Test the server:**

* Open [`http://localhost:3000/home`](http://localhost:3000/home) to see the HTML file served by the Node.js server.
    

---

#### **Task 5: Handle Query Parameters**

**What to do:**

* Handle query parameters from a URL and return dynamic content based on those parameters.
    

**Example:**

```javascript
const http = require("http");
const url = require("url");

// Create an HTTP server
const server = http.createServer((req, res) => {
  // Parse the URL and extract query parameters
  const parsedUrl = url.parse(req.url, true);
  const queryObject = parsedUrl.query;

  // Check if the path starts with /greet/
  if (req.url.startsWith("/greet/")) {
    // Extract the "name" query parameter, or default to "Guest"
    const name = queryObject.name || "Guest";

    // Set response header and send the greeting message
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end(`Hello, ${name}!`);
  } else {
    // Handle 404 Not Found if the route doesn't match /greet/
    res.writeHead(404, { "Content-Type": "text/plain" });
    res.end("404 - Not Found");
  }
});

// The server listens on port 3000
server.listen(3000, () => {
  console.log("Server is listening on port 3000...");
});
```

**Test the server:**

* Open [`http://localhost:3000/greet?name=John`](http://localhost:3000/greet?name=John) to see dynamic content generated based on the query parameter (`name=John`).
