Create HTTP Web Server in Node.js

In Node.js, we manually create a server that lives in the backend of our website. This server actively listens for requests from the browser and responses to them.

I. How to create an HTTP server?

Firstly, we’ll need to import the http node core module:

const http = require("http");

Then, we use the http.createServer() method, which takes in a callback function as an argument. This callback function runs every time a request comes in.

The callback function has two objects:

  • req: Request object contains all information about the request: url, request type, etc.
  • res: Response object sends a response to the users and browsers
const server = http.createServer((req, res) => {
  console.log("request was made");
});

To make the server actively listen to the requests, we need to invoke the listen method server.listen() and pass in 3 arguments:

  • The port number.
  • The host name. The default value is localhost.
  • A function that fires when it listens for a request.
server.listen(3000, "localhost", () => {
  console.log("listening for request");
});

II. The response object

To send a response to the browser, we need the following steps:

  • Set the response header with setHeader(). It’ll give the browser the type of response coming back to it (text, HTML, JSON, etc.).
  • Write the response.
  • End the response.

Example: Response a plain text

const http = require("http");

const server = http.createServer((req, res) => {
  console.log("request was made");

  // Set header content type
  res.setHeader("Content-Type", "text/plain");

  // Write and end response
  res.write("Hello, world");
  res.end();
});

server.listen(3000, "localhost", () => {
  console.log("listening for request");
});

So if we open http://localhost:3000/, we’ll see the text “Hello, world”.

Example: Response HTML

const http = require("http");

const server = http.createServer((req, res) => {
  console.log("request was made");

  // Set header content type
  res.setHeader("Content-Type", "text/html");

  // Write and end response
  res.write("<p>Hello, world</p>");
  res.write("<p>Hello, again</p>");
  res.end();
});

server.listen(3000, "localhost", () => {
  console.log("listening for request");
});

III. Returning HTML pages

In this section, we’ll learn how to send a complete HTML page to the browser.

For example, we have an HTML file:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title lang="en-US">Node.js Web server</title>
  </head>
  <body>
    <h1>Node.js Web server</h1>
    <p>This is a paragraph.</p>
  </body>
</html>

In our server.js file, we will need to import the fs module and read the HTML file:

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

const server = http.createServer((req, res) => {
  console.log("request was made");

  // Set header content type
  res.setHeader("Content-Type", "text/html");

  // Send an HTML file
  fs.readFile("./views/index.html", (err, data) => {
    if (err) {
      console.log(err);
      res.end();
    } else {
      res.write(data);
      res.end();
    }
  });
});

server.listen(3000, "localhost", () => {
  console.log("listening for request");
});

If we only send one thing to the res.write(), we can directly send it to the res.end() method.

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

const server = http.createServer((req, res) => {
  console.log("request was made");

  res.setHeader("Content-Type", "text/html");

  fs.readFile("./views/index.html", (err, data) => {
    if (err) {
      console.log(err);
      res.end();
    } else {
      // res.write(data);
      res.end(data);
    }
  });
});

server.listen(3000, "localhost", () => {
  console.log("listening for request");
});

IV. Basic Routing

We can use switch to provide basic routing for a website.

For example, we’ll send users to the About page if they access /about and the 404 page if they access non-exist pages.

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

const server = http.createServer((req, res) => {
  console.log("request was made");

  // Set header content type
  res.setHeader("Content-Type", "text/html");

  // Routing
  let path = "./views/";
  switch (req.url) {
    case "/":
      path += "index.html";
      break;
    case "/about":
      path += "about.html";
      break;
    default:
      path += "404.html";
  }

  // Send Html
  fs.readFile(path, (err, data) => {
    if (err) {
      console.log(err);
      res.end();
    }
    res.end(data);
  });
});

server.listen(3000, "localhost", () => {
  console.log("listening for request");
});

Status code

The status code describes the type of response sent to the browser. They are in the range of 100 to 500:

  • 100 range: informational responses
  • 200 range: success codes
  • 300 range: redirect codes
  • 400 range: user or client error codes
  • 500 range: server error codes

The most common status codes are:

  • 200: OK
  • 301: Resource removed
  • 404: Not found
  • 500: Internal server error

To set the status code for responses, we use res.statusCode:

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

const server = http.createServer((req, res) => {
  console.log("request was made");

  // Set header content type
  res.setHeader("Content-Type", "text/html");

  // Routing
  let path = "./views/";
  switch (req.url) {
    case "/":
      path += "index.html";
      res.statusCode = 200;
      break;
    case "/about":
      path += "about.html";
      res.statusCode = 200;
      break;
    default:
      path += "404.html";
      res.statusCode = 404;
  }

  // Send html
  fs.readFile(path, (err, data) => {
    if (err) {
      console.log(err);
      res.end();
    }
    res.end(data);
  });
});

server.listen(3000, "localhost", () => {
  console.log("listening for request");
});

Redirect

To redirect one page to another, we use the setHeader() method.

For example, we no longer have the /about-us page, so we redirect it to /about page.

case "/about-us":
      res.statusCode = 301;
      res.setHeader("Location", "/about");
      res.end();
      break;