Build a REST API with Node.js: HTTP Module & Express

Subscribe to my newsletter and never miss my upcoming articles

Hello everyone! First, a huge thank you to everyone who gave me great reactions and wonderful comments as soon as I launched this series. I'm so glad you are excited about this series as much as I do!

Next, let's move on to why I am writing this article. One of my readers who read part 1 of the series, Designing & Planning your API, suggests that I elaborate a little more on the HTTP module and why we need to include Express or any web framework to use for our API. And so, here's an unplanned, last-minute mini article (hence, part 1.5) that I put together for anyone who is curious about the topic.

The HTTP Module

Node.js has a built-in HTTP module which it uses to make HTTP requests and transfer data from the server to the client. Here's a diagram illustrating how it works.

http module.png

According to its documentation, a typical process of how Node.js handles HTTP transactions is as follows:

  1. Instantiate an HTTP server with a request handler function, and have it listen on a port.
  2. Get headers, URL, method and body data from request objects.
  3. Send headers, HTTP status codes and body data via response objects.
  4. Pipe data from request objects and to response objects.
  5. Handle errors in both the request and response streams.

In code, it looks like:

//1.
const http = require('http');

//2.
http.createServer((request, response) => {
  const { headers, method, url } = request;
  let body = [];
  request.on('error', (err) => {
    console.error(err);
  }).on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    body = Buffer.concat(body).toString();

//3.
    response.statusCode = 200;
    response.setHeader('Content-Type', 'application/json');
    const responseBody = { headers, method, url, body };

//4.
    response.write(JSON.stringify(responseBody));

//5.
    response.on('error', (err) => {
      console.error(err);
    });

    response.end();

  });
}).listen(8080);

As you can see in the code above, it looks really long and tedious to write. Moreover, this is only a skeleton example. To handle requests with different payloads (body), routes and adding middleware, we would have to write longer and more tedious code.

And so... we use web frameworks like Express to save us a lot of time from writing repetitive code because it makes it so simple to implement routes and add middleware. It also adds a layer of security to our applications by eliminating human errors (i.e. not escaping certain characters) that comes from manually creating a server with plain Node.js.

Let's write the Express equivalent of our earlier code:

const express=require('express');
const app=express();

// add midddleware here

app.get("/", function (req, res) {
  res.send(req.headers, req.originalUrl, req.method, req.body);
});

app.listen(3000, () =>
  console.log('Example app listening on port 3000!'),
);

That's so much more concise! And you can do even more things with Express such as:

  • adding middleware at any point between the app instantiation and routes or even at individual routes
  • adding handlers for requests with different HTTP methods at different routes
  • send responses with parsed and readable formats
  • set common settings like the port to use for connecting and where to render the response

And that's why Express is our hero!

Thanks for reading. I hope it is clear now why Express.js or any other web frameworks like Sails.js or Adonis.js is recommended to use when creating a server with Node. Some extra reading for you if you want to know more about the HTTP module in Node or Express:

Please stay tuned to part 2 of the series! Special thanks to Subha Chanda for suggesting this topic. Have a nice day and cheers!

Comments (2)

Subha Chanda's photo

Whoa! Didn't expected so soon. 😅 BTW, short and clear article. Thanks for sharing. 😊

Victoria Lo's photo

No problem! It's a mini article. Didn't take me long :) Glad you find it useful!