惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
WordPress大学
WordPress大学
博客园 - 司徒正美
美团技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
量子位
阮一峰的网络日志
阮一峰的网络日志
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
博客园 - Franky
Jina AI
Jina AI
人人都是产品经理
人人都是产品经理
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Threat Research - Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fox-IT International blog
T
ThreatConnect
A
Arctic Wolf
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
C
CERT Recently Published Vulnerability Notes
P
Palo Alto Networks Blog
李成银的技术随笔
Project Zero
Project Zero
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Register - Security
The Register - Security
F
Full Disclosure
H
Hacker News: Front Page
雷峰网
雷峰网
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
SegmentFault 最新的问题
S
Schneier on Security
T
Tor Project blog
博客园_首页
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
S
Securelist
C
Comments on: Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Attack and Defense Labs
Attack and Defense Labs
IT之家
IT之家
博客园 - 叶小钗
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events

DEV Community

RP2040 Wristwatch Tells Time With a Vintage VU Meter Needle AI Agent Dev Environment Guide — Real Experience from an AI Living Inside a Server How I Run 7 AI Models 24/7: Multi-Agent Architecture in Practice What exactly changes with the Claude Max plan? I Revived a Broken MLOps Platform — Now It's Self-Service, Policy-Guarded, and Operationally Credible OpenAI's $2M-tokens-for-equity YC deal, decoded Why DMX Infrastructure is Still Stuck in the 90s Agent Series (2): ReAct — The Most Important Agent Reasoning Paradigm Open Source Project (No.73): Sub2API - All-in-One Claude/OpenAI/Gemini Subscription-to-API Relay I Made the Wrong Bet on Event Streaming in Our Treasure Hunt Engine #ai #productivity #chatgpt #python Symbolic Constant Conundrum From Manual RAG to Real Retrieval — Embedding-Based RAG with NVIDIA NIM Building an outbound-only WebSocket bridge for local AI agents Our System's Sins in Ghana: Why We Had to Rethink Digital Product Sales Execution Governance, AI Drift, and the Security Paradox of Runtime Enforcement Differential Pair Impedance: Why USB and HDMI Routing Is a Geometry Problem Small AI database questions can become big scans Claude Code 2.1 Agent View & /goal: Autonomous Dev Guide 2026 Your AI database agent should not see every column Rust's Low-Latency Conquest: Why We Ditched C++ for a Treasure Hunt Engine Floating-point will quietly corrupt your emissions math, and 0.1 + 0.2 already warned you Autonomous Agents: what breaks first (and why that's the real product) [2026-05-23] Agent payments are the new cloud bill footgun ORA-00069 오류 원인과 해결 방법 완벽 가이드 How I Built a Local, Multimodal Gemma 4 Visual Regression & Patch Agent: Closed-Loop Validation, Canvas Pixel Diffing, and Reproducible Benchmarks Pressure-testing Ota on Supabase: from setup prose to executable repo readiness VPC CNI en EKS: cómo dejar de pagar nodos que no usás The Future of Text Analysis: Introducing TechnoHelps Semantic Engine I built a Chrome Extension that saves product images + context directly to Google Drive & Sheets 95+ browser-based dev tools that never touch a server Running Qwen 2.5 Coder 14B Locally in Cursor with Ollama From a 10,000-line OpenSearch export script to a log analysis tool Ghost Bugs Cost $40K: A Neural Debugging Postmortem SECPAC: A Lightweight CLI Tool to Password-Protect Your Environment Variables 🚀 PasteCheck v1.7 + v1.8 — Hints that tell you what to fix, and a nudge panel that tells you where to start 8 Real Ways Developers Make Money in 2026 (Ranked by Effort) I built a free AI-powered Git CLI that writes your commit messages for you sds-converter: Converting Safety Data Sheets to MHLW Standard JSON with Rust and LLMs OpenLiDARViewer: A Browser-Based LiDAR and Point-Cloud Viewer Local-First Browser Tools: What You Should Not Upload Online Why most freelancers undercharge (and the maths behind fixing it) We built a mahjong dangerous-tile predictor calibrated on 4.97M real hands Building a Chord Progression Generator in the Browser — Music Theory in JS, Sound via Web Audio API tutorial #10: 148 Opens, 0 Replies — How My Forge Cold Email v1 Completely Failed 9 in 10 Docker Compose files skip the basic security flags How to Forward Android SMS to Telegram Automatically I built the first security scanner for MCP servers — here's what I found Building an Interplanetary Quantum Logic Engine in Rust/Ovie From AI Code Generation to AI System Investigation I gave Gemini 3.5 Flash a CVE-fix PR to review. It found another bug in the same file. When I Realized We Were Throwing Away Half Our Engine's Potential TokenJuice and the 20-Minute Cron: Inside OpenHuman’s Aggressive Context-Harvesting Engine CodeDNA: AI Codebase Archaeologist Built with Gemma 4 Thinking Mode Building a semantic search API in Go with Meilisearch April 2026 DigitalOcean Tutorials: Inference Optimization and AI Infrastructure Looking for DTMF transceiver module Moving Beyond "Tribal Software": Why the Singularity Demands the Interplanetary Hybrid Human Use SVGIcons as a Claude Custom Connector to Find Icons Faster DMARC Is Now a Proper Internet Standard: What Changed in RFC 9989/9990/9991 OpenTelemetry Is Now a CNCF Graduate — and It's Coming for Your AI Stack OpenHuman Follows OpenClaw’s Rise, But With an Obsidian Brain O erro mais caro em programas Solana: PDA sem bump check Build a Live Flight Radar in a Single HTML File DuckDB 1.5.3 Adds Quack Client-Server, SQLite Gets Cypher Graph Extension Custom Copilot Agents: Building Domain-Expert AI Teammates with Skills, MCP Tools, and Custom Knowledge RTX 5090 Cooling, BeeLlama VRAM Opts, Resizable BAR Performance Gains This week in Cursor + .NET — 3 rules + 4 essays (week ending May 22, 2026) RAG Architecture with n8n + PostgreSQL (pgvector) + Ollama Gemma4 on AWS EC2 Keep Your Taste I Built chanprobe Because My Go Queues Were Invisible Building a Live Solana TPS Meter with OrbitFlare's TypeScript SDK Using Gemma 4 to Analyze Bitcoin’s Next 5, 15, and 60 Minutes Security news weekly round-up - 22nd May 2026 When Stress Disguises Itself as Rational Planning (Bite-size Article) A Domain-Driven Notification Microservice — Patterns From Production I Built KubeCrash: Learn Kubernetes by Diagnosing Real Incidents The Real-World Test: How Gemini’s New Interface Won Over My Wife and Mother-in-Law (Who Are Totally Non-Tech) Running a Full Multi-Stage Intrusion Simulation. Every Detection Fired. Spec sheets aren't capabilities: a Day-1 Gemma 4 eval on Telugu vision Design a Clean Form with Floating Labels in Bootstrap 5 Your MCP Server Is Probably Overprivileged - Here's a Scanner For It I built a free developer tools site that works entirely in your browser Maatru: An agentic Telugu literacy app for kids, built with Gemma 4 GitHub confirms internal repository breach via poisoned VS Code extension Gemma 4 Is Not Just Another Open Model — It Changes What Developers Can Build Locally OpenVibe: An Open-Source AI Coding IDE That Works With Any Model I Inspected the System Program and It Looked Just Like My Wallet Hermes vs OpenClaw: The Two Most-Starred AI Agent Frameworks of 2026 Stop retraining YOLO: a developer’s guide to zero-shot object detection with generative VLMs AI, the New UI, Not the New API Sensors and Guides: Two Ways Your Harness Talks to Your Agent Fixing Google BigQuery Auth Proxying We didn't ship a feature, we shipped an agentic opt-in beta Wake-Up Call: Why AI Safety Guardrails Break Under Pressure 🧩 Handling 1,000+ Inputs with Angular Reactive Forms: An Enterprise Architecture Breakdown How to Collect Telegram Media Groups in Node.js I Ran Gemma 4 on an 8GB Laptop — Here’s What the Experience Was Actually Like Lean 4 101 for Python Programmers: A Gentle Introduction to Theorem Proving From Assistants to Agents: My Take on Google I/O 2026
Mastering Node.js HTTP Module: Build Servers, REST APIs, and Handle Requests
coding sprin · 2026-05-23 · via DEV Community

Introduction to the HTTP Module

Modern web applications rely heavily on communication between clients and servers. Whether you are building a REST API, handling browser requests, or serving files, understanding the HTTP module in Node.js is a foundational skill every backend developer should master.

Node.js provides a built-in HTTP module that allows developers to create servers, manage requests and responses, handle routing, and even stream large amounts of data efficiently — all without installing external packages.

In this article, we’ll explore the Node.js HTTP module in depth with practical examples, explanations, best practices, and real-world usage scenarios.

What is HTTP?

HTTP stands for:

HyperText Transfer Protocol

It is the protocol used for communication between:

  • Browsers and web servers
  • Frontend and backend applications
  • APIs and clients

When you visit a website:

  1. Your browser sends an HTTP request
  2. The server processes it
  3. The server sends back an HTTP response

Key Features:

  • Create HTTP servers to handle requests and send responses
  • Make HTTP requests to other servers
  • Handle different HTTP methods (GET, POST, PUT, DELETE, etc.)
  • Work with request and response headers
  • Handle streaming data for large payloads

Importing the HTTP Module

Node.js uses the require() function to import modules.

const http = require('http');

Enter fullscreen mode Exit fullscreen mode

If you are using ES Modules:

import http from 'http';

Enter fullscreen mode Exit fullscreen mode

Creating Your First HTTP Server

Let’s build a simple Node.js server.

const http = require('http');

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

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

  res.end('Hello, World!');
});

server.listen(3000, () => {
  console.log('Server running on port 3000');
});

Enter fullscreen mode Exit fullscreen mode

Understanding the Server Code

http.createServer()

Creates an HTTP server.

Parameters

  • req → Request object
  • res → Response object

res.writeHead()

Used to set:

  • Status code
  • Headers
res.writeHead(200, {
  'Content-Type': 'text/plain'
});

Enter fullscreen mode Exit fullscreen mode

res.end()

Sends the response and closes the connection.

res.end('Hello World');

Enter fullscreen mode Exit fullscreen mode

server.listen()

Starts the server.

server.listen(3000);

Enter fullscreen mode Exit fullscreen mode

Running the Server

Save the code in a file named server.js
Run the server using Node.js:

node server.js

Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:3000 in your browser to see the response.

Working with HTTP Headers

HTTP headers let you send additional information with your response.
The res.writeHead() method is used to set the status code and response headers.

Setting Response Headers

const http = require('http');

const server = http.createServer((req, res) => {
  // Set status code and multiple headers
  res.writeHead(200, {
    'Content-Type': 'text/html',
    'X-Powered-By': 'Node.js',
    'Cache-Control': 'no-cache, no-store, must-revalidate',
    'Set-Cookie': 'sessionid=abc123; HttpOnly'
  });

  res.end('<h1>Hello, World!</h1>');
});

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

Enter fullscreen mode Exit fullscreen mode

Common HTTP Status Codes

Code Message Description
200 OK Standard response for successful HTTP requests
201 Created Request has been fulfilled and new resource created
301 Moved Permanently Resource has been moved to a new URL
400 Bad Request Server cannot process the request due to client error
401 Unauthorized Authentication is required
403 Forbidden Server refuses to authorize the request
404 Not Found Requested resource could not be found
500 Internal Server Error Unexpected condition was encountered

Common Response Headers

  • Content-Type: Specifies the media type of the content (e.g., text/html, application/json)
  • Content-Length: The length of the response body in bytes
  • Location: Used in redirects (with 3xx status codes)
  • Set-Cookie: Sets HTTP cookies on the client
  • Cache-Control: Directives for caching mechanisms
  • Access-Control-Allow-Origin: For CORS support

Reading Request Headers

You can access request headers using the req.headers object:

const http = require('http');

const server = http.createServer((req, res) => {
  // Log all request headers
  console.log('Request Headers:', req.headers);

  // Get specific headers (case-insensitive)
  const userAgent = req.headers['user-agent'];
  const acceptLanguage = req.headers['accept-language'];

  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end(`User-Agent: ${userAgent}\nAccept-Language: ${acceptLanguage}`);
});

server.listen(3000);

// User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36
// Accept-Language: en-US,en;q=0.9,nb;q=0.8,da;q=0.7,no;q=0.6

Enter fullscreen mode Exit fullscreen mode

Working with URLs and Query Strings

Node.js provides built-in modules for working with URLs and query strings, making it easy to parse URL components and query parameters.

Accessing the Request URL

The req.url property contains the URL string that was requested, including any query parameters.

This is part of the http.IncomingMessage object.

const http = require('http');

const server = http.createServer((req, res) => {
  // Get the URL and HTTP method
  const { url, method } = req;

  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end(`You made a ${method} request to ${url}`);
});

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

// You made a GET request to /

Enter fullscreen mode Exit fullscreen mode

Parsing URLs with the URL Module

The url module provides utilities for URL resolution and parsing.

It can parse a URL string into a URL object with properties for each part of the URL.

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

const server = http.createServer((req, res) => {
  // Parse the URL
  const parsedUrl = url.parse(req.url, true);

  // Get different parts of the URL
  const pathname = parsedUrl.pathname; // The path without query string
  const query = parsedUrl.query; // The query string as an object

  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    pathname,
    query,
    fullUrl: req.url
  }, null, 2));
});

server.listen(3000);

Enter fullscreen mode Exit fullscreen mode

Example Requests and Responses

For the following request:

GET /products?category=electronics&sort=price&page=2 HTTP/1.1

The server would respond with:

{
"pathname": "/products",
"query": {
"category": "electronics",
"sort": "price",
"page": "2"
},
"fullUrl": "/products?category=electronics&sort=price&page=2"
}

Working with Query Strings

For more advanced query string handling, you can use the querystring module:

const http = require('http');
const { URL } = require('url');
const querystring = require('querystring');

const server = http.createServer((req, res) => {
  // Using the newer URL API (Node.js 10+)
  const baseURL = 'http://' + req.headers.host + '/';   const parsedUrl = new URL(req.url, baseURL);

  // Get query parameters
  const params = Object.fromEntries(parsedUrl.searchParams);

  // Example of building a query string
  const queryObj = {
    name: 'John Doe',
    age: 30,
    interests: ['programming', 'music']
  };
  const queryStr = querystring.stringify(queryObj);

  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    path: parsedUrl.pathname,
    params,
    exampleQueryString: queryStr
  }, null, 2));
});

server.listen(3000);

Enter fullscreen mode Exit fullscreen mode

{
  "path": "/",
  "params": {},
  "exampleQueryString": "name=John%20Doe&age=30&interests=programming&interests=music"
}

Enter fullscreen mode Exit fullscreen mode

Common URL Parsing Methods

  • url.parse(urlString, [parseQueryString], [slashesDenoteHost]): Parse a URL string into an object
  • url.format(urlObject): Format a URL object into a URL string
  • url.resolve(from, to): Resolve a target URL relative to a base URL
  • new URL(input, [base]): The WHATWG URL API (recommended for new code)
  • querystring.parse(str, [sep], [eq], [options]): Parse a query string into an object
  • querystring.stringify(obj, [sep], [eq], [options]): Stringify an object into a query string

Handling Different HTTP Methods

RESTful APIs commonly use different HTTP methods (GET, POST, PUT, DELETE, etc.) to perform different operations on resources.

Here's how to handle different HTTP methods in a Node.js HTTP server:

Example: Handling Multiple HTTP Methods

const http = require('http');
const { URL } = require('url');

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

const server = http.createServer((req, res) => {
  const { method, url } = req;
  const parsedUrl = new URL(url, `http://${req.headers.host}`);
  const pathname = parsedUrl.pathname;

  // Set CORS headers (for development)
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

  // Handle preflight requests
  if (method === 'OPTIONS') {
    res.writeHead(204);
    res.end();
    return;
  }

  // Route: GET /todos
  if (method === 'GET' && pathname === '/todos') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify(todos));
  }
  // Route: POST /todos
  else if (method === 'POST' && pathname === '/todos') {
    let body = '';
    req.on('data', chunk => {
      body += chunk.toString();
    });

    req.on('end', () => {
      try {
        const newTodo = JSON.parse(body);
        newTodo.id = todos.length > 0 ? Math.max(...todos.map(t => t.id)) + 1 : 1;
        todos.push(newTodo);
        res.writeHead(201, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify(newTodo));
      } catch (error) {
        res.writeHead(400, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ error: 'Invalid JSON' }));
      }
    });
  }

  // Route: PUT /todos/:id
  else if (method === 'PUT' && pathname.startsWith('/todos/')) {
    const id = parseInt(pathname.split('/')[2]);
    let body = '';

    req.on('data', chunk => {
      body += chunk.toString();
    });

    req.on('end', () => {
      try {
        const updatedTodo = JSON.parse(body);
        const index = todos.findIndex(t => t.id === id);

        if (index === -1) {
          res.writeHead(404, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({ error: 'Todo not found' }));
        } else {
          todos[index] = { ...todos[index], ...updatedTodo };
          res.writeHead(200, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify(todos[index]));
        }
      } catch (error) {
        res.writeHead(400, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ error: 'Invalid JSON' }));
      }
    });
  }

  // Route: DELETE /todos/:id
  else if (method === 'DELETE' && pathname.startsWith('/todos/')) {
    const id = parseInt(pathname.split('/')[2]);
    const index = todos.findIndex(t => t.id === id);

    if (index === -1) {
      res.writeHead(404, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ error: 'Todo not found' }));
    } else {
      todos = todos.filter(t => t.id !== id);
      res.writeHead(204);
      res.end();
    }
  }

  // 404 Not Found
  else {
    res.writeHead(404, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ error: 'Not Found' }));
  }
});

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

Enter fullscreen mode Exit fullscreen mode

Testing the API with cURL

You can test this API using cURL commands:

# 1. Get all todos
curl http://localhost:3000/todos

# 2. Create a new todo
curl -X POST http://localhost:3000/todos \
-H "Content-Type: application/json" \
-d '{"task":"New Task","completed":false}'

# 3. Update a todo
curl -X PUT http://localhost:3000/todos/1 \
-H "Content-Type: application/json" \
-d '{"completed":true}'

# 4. Delete a todo
curl -X DELETE http://localhost:3000/todos/1

Enter fullscreen mode Exit fullscreen mode

Best Practices for HTTP Methods

  • GET: Retrieve a resource or collection of resources (should be idempotent)
  • POST: Create a new resource (not idempotent)
  • PUT: Update an existing resource or create it if it doesn't exist (idempotent)
  • PATCH: Partially update a resource
  • DELETE: Remove a resource (idempotent)
  • HEAD: Same as GET but without the response body
  • OPTIONS: Describe the communication options for the target resource

Error Handling

Always include proper error handling and appropriate HTTP status codes:

  • 200 OK - Successful GET/PUT/PATCH
  • 201 Created - Successful resource creation
  • 204 No Content - Successful DELETE
  • 400 Bad Request - Invalid request data
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Not enough permissions
  • 404 Not Found - Resource doesn't exist
  • 500 Internal Server Error - Server-side error

Streaming Responses

Node.js streams are powerful for handling large amounts of data efficiently. The HTTP module works well with streams for both reading request bodies and writing responses.

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

const server = http.createServer((req, res) => {
  // Get the file path from the URL
  const filePath = path.join(__dirname, req.url);

  // Check if file exists
  fs.access(filePath, fs.constants.F_OK, (err) => {
    if (err) {
      res.statusCode = 404;
      res.end('File not found');
      return;
    }

    // Get file stats
    fs.stat(filePath, (err, stats) => {
      if (err) {
        res.statusCode = 500;
        res.end('Server error');
        return;
      }

      // Set appropriate headers
      res.setHeader('Content-Length', stats.size);
      res.setHeader('Content-Type', 'application/octet-stream');

      // Create read stream and pipe to response
      const stream = fs.createReadStream(filePath);

      // Handle errors
      stream.on('error', (err) => {
        console.error('Error reading file:', err);
        if (!res.headersSent) {
          res.statusCode = 500;
          res.end('Error reading file');
        }
      });

      // Pipe the file to the response
      stream.pipe(res);
    });
  });
});

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

Enter fullscreen mode Exit fullscreen mode

Benefits of Streaming

  • Memory Efficiency: Processes data in chunks instead of loading everything into memory
  • Faster Time to First Byte: Starts sending data as soon as it's available
  • Backpressure Handling: Automatically handles slow clients by pausing the read stream

Common Use Cases for Streaming

  • File uploads/downloads
  • Real-time data processing
  • Proxying requests
  • Video/audio streaming
  • Log processing

Final Thoughts

The Node.js HTTP module is one of the most important building blocks in backend development. While frameworks like Express simplify development, understanding the core HTTP module gives you deeper insight into how web servers, APIs, and request-response cycles actually work.

Mastering this module will help you:

  • Build scalable backend systems
  • Understand REST APIs deeply
  • Improve debugging skills
  • Handle streams efficiently
  • Become a stronger Node.js developer

If you're serious about backend engineering, learning the HTTP module thoroughly is absolutely worth your time. 🚀