Create HTTP Web Server in Node.js

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

I. How to create a HTTP server?

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

const http = require("http");

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

The callback function has 2 objects:

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

To make 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. Default value is localhost
  • A function that fires when it listens for request
server.listen(3000, "localhost", () => {
  console.log("listening for request");
});

II. The response object

To send response to the browser, we need do 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 full 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 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 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 website.

For example, we’ll send users to About page if they access /about and 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

Status code describes the type of response sent to the browser. They are in the range from 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 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 setHeader() method.

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

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