Node.js Intermediate

Building HTTP Servers with Node.js: Handling Web Requests

CodingerWeb
CodingerWeb
19 views 60 min read

HTTP Module in Node.js

Node.js includes a built-in http module that allows you to create HTTP servers and clients. This is the foundation for building web applications and APIs.

Creating Your First HTTP Server

const http = require("http");

// Create a simple server
const server = http.createServer((req, res) => {
    // Set response headers
    res.writeHead(200, { "Content-Type": "text/plain" });
    
    // Send response
    res.end("Hello, World! This is my first Node.js server.");
});

// Start the server
const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}/`);
});

Handling Different Routes

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

const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    const path = parsedUrl.pathname;
    const method = req.method;
    
    // Set common headers
    res.setHeader("Content-Type", "application/json");
    
    if (path === "/" && method === "GET") {
        res.writeHead(200);
        res.end(JSON.stringify({
            message: "Welcome to the homepage!",
            timestamp: new Date().toISOString()
        }));
    } else if (path === "/about" && method === "GET") {
        res.writeHead(200);
        res.end(JSON.stringify({
            message: "About page",
            version: "1.0.0",
            author: "Node.js Developer"
        }));
    } else if (path === "/users" && method === "GET") {
        // Simulate user data
        const users = [
            { id: 1, name: "John Doe", email: "john@example.com" },
            { id: 2, name: "Jane Smith", email: "jane@example.com" }
        ];
        
        res.writeHead(200);
        res.end(JSON.stringify({ users }));
    } else {
        // 404 Not Found
        res.writeHead(404);
        res.end(JSON.stringify({
            error: "Page not found",
            path: path,
            method: method
        }));
    }
});

server.listen(3000, () => {
    console.log("Server running on http://localhost:3000");
});

Handling POST Requests and Request Body

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

const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    const path = parsedUrl.pathname;
    const method = req.method;
    
    // Handle POST request with body
    if (path === "/users" && method === "POST") {
        let body = "";
        
        // Collect data chunks
        req.on("data", (chunk) => {
            body += chunk.toString();
        });
        
        // Process complete request
        req.on("end", () => {
            try {
                const userData = JSON.parse(body);
                
                // Validate required fields
                if (!userData.name || !userData.email) {
                    res.writeHead(400, { "Content-Type": "application/json" });
                    res.end(JSON.stringify({
                        error: "Name and email are required"
                    }));
                    return;
                }
                
                // Simulate saving user
                const newUser = {
                    id: Date.now(),
                    name: userData.name,
                    email: userData.email,
                    created: new Date().toISOString()
                };
                
                res.writeHead(201, { "Content-Type": "application/json" });
                res.end(JSON.stringify({
                    message: "User created successfully",
                    user: newUser
                }));
                
            } catch (err) {
                res.writeHead(400, { "Content-Type": "application/json" });
                res.end(JSON.stringify({
                    error: "Invalid JSON data"
                }));
            }
        });
    } else {
        res.writeHead(404, { "Content-Type": "application/json" });
        res.end(JSON.stringify({ error: "Endpoint not found" }));
    }
});

server.listen(3000, () => {
    console.log("Server running on http://localhost:3000");
});

Serving Static Files

const http = require("http");
const fs = require("fs");
const path = require("path");

// MIME types for different file extensions
const mimeTypes = {
    ".html": "text/html",
    ".css": "text/css",
    ".js": "text/javascript",
    ".json": "application/json",
    ".png": "image/png",
    ".jpg": "image/jpeg",
    ".gif": "image/gif",
    ".ico": "image/x-icon"
};

const server = http.createServer((req, res) => {
    let filePath = "." + req.url;
    
    // Default to index.html for root path
    if (filePath === "./") {
        filePath = "./index.html";
    }
    
    // Get file extension
    const extname = String(path.extname(filePath)).toLowerCase();
    const mimeType = mimeTypes[extname] || "application/octet-stream";
    
    // Read and serve file
    fs.readFile(filePath, (err, content) => {
        if (err) {
            if (err.code === "ENOENT") {
                // File not found
                res.writeHead(404, { "Content-Type": "text/html" });
                res.end("

404 - File Not Found

"); } else { // Server error res.writeHead(500); res.end(`Server Error: ${err.code}`); } } else { // Success res.writeHead(200, { "Content-Type": mimeType }); res.end(content, "utf-8"); } }); }); server.listen(3000, () => { console.log("Static file server running on http://localhost:3000"); });

Building a Simple API Server

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

// In-memory data store
let todos = [
    { id: 1, task: "Learn Node.js", completed: false },
    { id: 2, task: "Build an API", completed: false }
];

let nextId = 3;

const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    const path = parsedUrl.pathname;
    const method = req.method;
    const query = parsedUrl.query;
    
    // CORS headers
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
    res.setHeader("Access-Control-Allow-Headers", "Content-Type");
    res.setHeader("Content-Type", "application/json");
    
    // Handle preflight requests
    if (method === "OPTIONS") {
        res.writeHead(200);
        res.end();
        return;
    }
    
    // Routes
    if (path === "/api/todos" && method === "GET") {
        res.writeHead(200);
        res.end(JSON.stringify({ todos }));
        
    } else if (path === "/api/todos" && method === "POST") {
        let body = "";
        req.on("data", chunk => body += chunk);
        req.on("end", () => {
            try {
                const { task } = JSON.parse(body);
                const newTodo = {
                    id: nextId++,
                    task,
                    completed: false
                };
                todos.push(newTodo);
                
                res.writeHead(201);
                res.end(JSON.stringify({ todo: newTodo }));
            } catch (err) {
                res.writeHead(400);
                res.end(JSON.stringify({ error: "Invalid JSON" }));
            }
        });
        
    } else if (path.startsWith("/api/todos/") && method === "PUT") {
        const id = parseInt(path.split("/")[3]);
        let body = "";
        
        req.on("data", chunk => body += chunk);
        req.on("end", () => {
            try {
                const { completed } = JSON.parse(body);
                const todo = todos.find(t => t.id === id);
                
                if (todo) {
                    todo.completed = completed;
                    res.writeHead(200);
                    res.end(JSON.stringify({ todo }));
                } else {
                    res.writeHead(404);
                    res.end(JSON.stringify({ error: "Todo not found" }));
                }
            } catch (err) {
                res.writeHead(400);
                res.end(JSON.stringify({ error: "Invalid JSON" }));
            }
        });
        
    } else {
        res.writeHead(404);
        res.end(JSON.stringify({ error: "Endpoint not found" }));
    }
});

server.listen(3000, () => {
    console.log("Todo API server running on http://localhost:3000");
});

Exercise

Create a simple blog API server that:

  1. Serves a list of blog posts (GET /api/posts)
  2. Creates new blog posts (POST /api/posts)
  3. Retrieves individual posts (GET /api/posts/:id)
  4. Serves static HTML files for the frontend

What's Next?

In the next lesson, we'll explore Express.js, a popular web framework that simplifies building web applications and APIs.