Complete Node.js HTTP Module Tutorial

A comprehensive guide to understanding and using HTTP in Node.js with clear explanations and simple examples.

HTTP Basics Server & Client Best Practices

Table of Contents

  1. What is HTTP?
  2. Understanding the HTTP Module
  3. Creating an HTTP Server
  4. Working with Requests
  5. Sending Responses
  6. HTTP Methods Explained
  7. Status Codes & Headers
  8. Making HTTP Requests (Client)
  9. Best Practices
  10. Interview Q&A + MCQ

1. What is HTTP?

The Theory

HTTP (Hypertext Transfer Protocol) is the foundation of web communication. It defines how clients and servers exchange data.

You (Client)                    Waiter (HTTP)                    Kitchen (Server)
    │                                │                                 │
    │  "I want a pizza"              │                                 │
    │ ──────────────────────────────>│                                 │
    │                                │  "Get pizza from kitchen"       │
    │                                │ ───────────────────────────────>│
    │                                │                                 │
    │                                │  "Here's your pizza"            │
    │                                │ <───────────────────────────────│
    │  "Here's your pizza"           │                                 │
    │ <──────────────────────────────│                                 │

Key Concepts

ConceptWhat it meansReal-world example
RequestClient asks server"Show homepage"
ResponseServer replies"Here is HTML"
MethodAction typeGET, POST, PUT, DELETE
Status CodeResult indicator200, 404, 500

2. Understanding the HTTP Module

The built-in http module helps you create servers and make outgoing HTTP requests.

const http = require('http'); // built-in, no installation needed
FeatureDescriptionUse case
http.createServer()Create HTTP serverWebsite/API backend
http.request()Generic HTTP requestCalling external APIs
http.get()Convenient GET helperSimple data fetch
const server = http.createServer((request, response) => {
    response.writeHead(200, { 'Content-Type': 'text/plain' });
    response.end('Hello, World!\n');
});

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

3. Creating an HTTP Server

Route-based example

const http = require('http');

const server = http.createServer((req, res) => {
    const path = req.url;

    if (path === '/') {
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.end('<h1>Home Page</h1>');
    } else if (path === '/about') {
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.end('<h1>About Us</h1>');
    } else if (path === '/api/time') {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ time: new Date().toISOString() }));
    } else {
        res.writeHead(404, { 'Content-Type': 'text/html' });
        res.end('<h1>404 - Not Found</h1>');
    }
});

server.listen(3000);

Request-response lifecycle

const server2 = http.createServer((req, res) => {
    console.log(req.method, req.url, req.headers);
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Hello from lifecycle example');
});

4. Working with Requests

URL and query parsing

const url = require('url');

const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    const path = parsedUrl.pathname;
    const queryParams = parsedUrl.query;
    res.end(`Path: ${path} Query: ${JSON.stringify(queryParams)}`);
});

Headers and body

if (req.method === 'POST') {
    let body = '';
    req.on('data', chunk => body += chunk.toString());
    req.on('end', () => {
        console.log('Body:', body);
        res.end('Received');
    });
}

5. Sending Responses

HTML, JSON, redirects, errors

if (req.url === '/json') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ ok: true }));
} else if (req.url === '/redirect') {
    res.writeHead(301, { 'Location': '/' });
    res.end();
} else if (req.url === '/error') {
    res.writeHead(500, { 'Content-Type': 'text/plain' });
    res.end('Server error');
}
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
res.write('<h1>Part 1</h1>');
res.end('<p>Final Part</p>');

6. HTTP Methods Explained

MethodActionExample
GETReadGET /todos
POSTCreatePOST /todos
PUTReplace updatePUT /todos/1
PATCHPartial updatePATCH /todos/1
DELETERemoveDELETE /todos/1
// Minimal CRUD pattern uses method + route matching
// GET /todos
// GET /todos/:id
// POST /todos
// PUT /todos/:id
// DELETE /todos/:id

7. Status Codes & Headers

Status ranges

2xx: Success
3xx: Redirect
4xx: Client Error
5xx: Server Error

Common content types

// HTML
res.writeHead(200, { 'Content-Type': 'text/html' });

// JSON
res.writeHead(200, { 'Content-Type': 'application/json' });

// Text
res.writeHead(200, { 'Content-Type': 'text/plain' });

// XML
res.writeHead(200, { 'Content-Type': 'application/xml' });
// Other useful headers
res.setHeader('Cache-Control', 'max-age=3600');
res.setHeader('X-Custom-Header', 'MyValue');
res.setHeader('Location', '/new-path');

8. Making HTTP Requests (Client)

GET request

const http = require('http');

http.get('http://jsonplaceholder.typicode.com/posts/1', (res) => {
    let data = '';
    res.on('data', chunk => data += chunk);
    res.on('end', () => console.log(JSON.parse(data)));
}).on('error', (err) => console.error(err.message));

POST request

const postData = JSON.stringify({ title: 'My New Post', body: 'Content', userId: 1 });
const options = {
    hostname: 'jsonplaceholder.typicode.com',
    port: 80,
    path: '/posts',
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(postData)
    }
};

const req = http.request(options, (res) => {
    let data = '';
    res.on('data', chunk => data += chunk);
    res.on('end', () => console.log(JSON.parse(data)));
});
req.on('error', err => console.error(err.message));
req.write(postData);
req.end();
// Promise helper
const https = require('https');
function fetchJSON(url) {
    return new Promise((resolve, reject) => {
        https.get(url, (res) => {
            let data = '';
            res.on('data', chunk => data += chunk);
            res.on('end', () => {
                try { resolve(JSON.parse(data)); } catch (e) { reject(e); }
            });
        }).on('error', reject);
    });
}

9. Best Practices

Error handling

server.on('error', (error) => {
    if (error.code === 'EADDRINUSE') console.error('Port already in use');
    else console.error(error);
});

Security headers

res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');

Timeout + body limits + logging + graceful shutdown

// Timeout
req.setTimeout(30000, () => {
    res.writeHead(408);
    res.end('Request Timeout');
    req.destroy();
});

// Body size limit
const MAX_SIZE = 1024 * 1024;

// Request logging
res.on('finish', () => console.log(`${req.method} ${req.url} - ${res.statusCode}`));

// Graceful shutdown
process.on('SIGTERM', () => {
    server.close(() => process.exit(0));
});

Quick Reference

// Server
const http = require('http');
const server = http.createServer((req, res) => {});
server.listen(3000);

// Request
req.method; req.url; req.headers;

// Response
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ ok: true }));
// Client
http.get('http://example.com', (res) => {});
const req = http.request(options, (res) => {});
req.write(data);
req.end();

10 Interview Questions + 10 MCQs

Interview Pattern 10 Q&A
1What is HTTP in simple terms?easy
Answer: A protocol that defines how clients and servers exchange web data.
2When should you use http.createServer()?easy
Answer: When building a Node.js HTTP server for websites or APIs.
3Difference between request and response?easy
Answer: Request is client input; response is server output.
4What does status code 404 mean?easy
Answer: Requested resource/route was not found.
5When do you read request body chunks?medium
Answer: For methods like POST/PUT/PATCH that send payload data.
6Why set Content-Type header?medium
Answer: So the client knows how to interpret response data (HTML/JSON/text/XML).
7What is the purpose of security headers?medium
Answer: They reduce common web attacks (sniffing, framing, XSS).
8How do you make an outgoing request in Node?medium
Answer: Using http.get() or http.request()/https.request().
9Why add request timeouts?hard
Answer: To prevent hanging connections from consuming resources forever.
10What is graceful shutdown?hard
Answer: Stop new connections, finish in-flight requests, then exit cleanly.

10 HTTP Module MCQs

1

Which module creates a native Node HTTP server?

Ahttp
Bnet
Curl
Dstream
Explanation: Use Node's built-in http module.
2

Best method for fetching a URL with GET?

Ahttp.post()
Bhttp.get()
Chttp.fetch()
Dhttp.load()
Explanation: http.get() is a convenience GET helper.
3

Which status code means resource created?

A200
B201
C301
D404
Explanation: 201 Created indicates successful creation.
4

Which header identifies response data format?

AAuthorization
BContent-Type
CUser-Agent
DCache-Control
Explanation: Content-Type tells clients how to parse body.
5

Which method is used to partially update a resource?

APUT
BPATCH
CPOST
DTRACE
Explanation: PATCH is for partial updates.
6

What does res.end() do?

ARestarts server
BFinalizes response
CParses JSON body
DCloses Node process
Explanation: It sends final chunk and ends HTTP response.
7

Which code indicates server-side failure?

A400
B404
C500
D304
Explanation: 500 is Internal Server Error.
8

Request metadata like browser info is in:

Areq.url
Breq.headers
Creq.socket only
Dres.body
Explanation: Headers store request metadata.
9

To parse POST payload, listen to:

Adata + end events
Bfinish event
Cclose only
Ddrain only
Explanation: Collect chunks on data, finalize on end.
10

Which signal is commonly handled for graceful shutdown?

ASIGTERM
BSIGKILL
CBREAK
DPAUSE
Explanation: Graceful shutdown usually handles SIGTERM/SIGINT.