Building a Simple HTTP Server with the Node.js http Module

One of the fundamental tasks of web development is creating HTTP servers. In Node.js, the built-in http module allows you to easily create a web server that listens for incoming requests and responds to them. In this module, we will explore how to build a simple HTTP server in Node.js, understanding its core components and the basic flow of an HTTP request/response cycle.


Table of Contents

  1. Introduction to the http Module
  2. Creating a Simple HTTP Server
  3. Handling Different HTTP Methods
  4. Parsing URL and Query Parameters
  5. Setting HTTP Headers
  6. Sending Responses
  7. Handling Errors
  8. Real-World Use Cases
  9. Conclusion

1. Introduction to the http Module

The http module in Node.js provides the functionality to create HTTP servers and clients. It allows Node.js applications to interact with HTTP requests and send HTTP responses. The http module is built-in and requires no installation.

To use it, simply require it in your code:

javascriptCopyEditconst http = require('http');

2. Creating a Simple HTTP Server

The basic structure of a Node.js HTTP server involves using http.createServer() to define how to handle incoming requests. The server listens for requests on a specified port.

javascriptCopyEditconst http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, World!\n');
});

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

When you run this, the server listens on port 3000 and responds with “Hello, World!” when accessed via a web browser or API client.


3. Handling Different HTTP Methods

An HTTP request can be of various methods, such as GET, POST, PUT, DELETE, etc. You can handle these methods differently based on the type of request.

javascriptCopyEditconst server = http.createServer((req, res) => {
  if (req.method === 'GET') {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('GET request received\n');
  } else if (req.method === 'POST') {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('POST request received\n');
  }
});

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

This example differentiates the response based on the HTTP method used in the request.


4. Parsing URL and Query Parameters

You can parse the URL and query parameters in the incoming request using req.url and the url module.

javascriptCopyEditconst url = require('url');

const server = http.createServer((req, res) => {
  const parsedUrl = url.parse(req.url, true);
  const name = parsedUrl.query.name || 'Guest';

  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end(`Hello, ${name}!\n`);
});

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

If you visit http://localhost:3000/?name=Alice, the server will respond with Hello, Alice!.


5. Setting HTTP Headers

HTTP headers provide additional information about the request or response. You can set headers using the setHeader() method.

javascriptCopyEditconst server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.setHeader('Cache-Control', 'no-store');
  res.end('Response with headers\n');
});

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

Here, the Cache-Control header is used to prevent the caching of the response.


6. Sending Responses

The res.end() method is used to send the response body. You can send plain text, HTML, JSON, or any other content type.

javascriptCopyEditconst server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'application/json');
  const responseData = { message: 'Hello, JSON!' };
  res.end(JSON.stringify(responseData));
});

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

This sends a JSON response to the client.


7. Handling Errors

You should handle errors properly to avoid crashes and ensure the server runs smoothly.

javascriptCopyEditconst server = http.createServer((req, res) => {
  try {
    if (req.url === '/error') {
      throw new Error('Something went wrong!');
    }
    res.statusCode = 200;
    res.end('Everything is fine');
  } catch (err) {
    res.statusCode = 500;
    res.end(`Error: ${err.message}`);
  }
});

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

This example demonstrates how to catch and handle errors gracefully.


8. Real-World Use Cases

  • APIs: Node.js HTTP servers are commonly used to build RESTful APIs.
  • Web Servers: A basic HTTP server serves as the foundation for building complex web applications.
  • Real-Time Applications: Use cases such as chat applications, live notifications, etc., rely on WebSockets, but the HTTP server still plays a vital role in initial communication.

9. Conclusion

Building an HTTP server in Node.js is simple yet powerful, giving you the flexibility to handle different HTTP methods, parse request URLs, and send dynamic responses. This serves as the foundation for creating APIs, websites, and real-time applications in Node.js.