Deep dive into the Node HTTP module

An in-depth look at the Node HTTP module, and how to use it to scale up!

The HTTP module is a core module of Node.js, it is fair to say it's one of the biggest responsible for Node's initial rise in popularity.

What You Will Learn#

  • To handle requests using Node and the HTTP module ✅

  • To handle post requests, and parse a body using the HTTP module ✅

  • To create an HTTPS server ✅

  • How to send HTTP requests ✅

Requirements#

  • Some experience with javascript.

  • An Installation of Node.js.

  • Some of you who are using windows should install GitBash.

  • Postman will come in handy to do some HTTP requests.

Overview of the HTTP protocol#

The Hypertext Transfer Protocol (HTTP) is an application-level protocol for distributed, collaborative, hypermedia information systems. It is a generic, stateless, protocol which can be used for many tasks beyond its use for hypertext, such as name servers and distributed object management systems, through extension of its request methods, error codes and headers [RFC2324]. A feature of HTTP is the typing and negotiation of data representation, allowing systems to be built independently of the data being transferred.

HTTP has been in use by the World-Wide Web global information initiative since 1990. This specification defines the protocol referred to as "HTTP/1.1", and is an update to RFC2616.

W3.org HTTP reference

HTTP is the veins of the internet, this website, any site you explore, you use the HTTP protocol to request it from a server, and the server uses the same HTTP protocol to send you back the data you requested.

Your first HTTP server using the HTTP module#

Let's import the module and create a basic HTTP server with it

We just created an HTTP Server object, some of its methods are:

  • Server.listen() Binds the server to listen to a specific port, this port binding is subject to permission restrictions, Unix TCP/IP ports bellow 1024 are privileged ports, so if you try to listen to port 80 (HTTP default port) your user running the node app might need special permissions, such as sudo.

  • Server.close() stops the server from listening to more requests, unbinds the server from the port.

While your server is still active and listening to new connections, the callback function you passed will be active in the event loop. This is the reason why our preview code snippet doesn't automatically exit after executing the last line of code. A node application will stay alive until there aren't more lines of code to execute or the event loop is still populated.

But if you call Server.close() then the event loop gets cleared, and the application will end.

For a complete list of HTTP server class properties and methods, check out the official docs.

Handling HTTP requests with the node http module#

In the example below, let's use the callback function to handle HTTP requests and respond to them.

req: shorthand for request, is an object from the class  IncomingMessage that includes all the request information. Some interesting properties are:

  • .connection contains all the connection information pertinent to the request such as .remoteAddress, that contains the network address that originated or forwarded the request.

  • .headers includes the headers attached to the request. If you visited the application at localhost:300 with your browser, one of the headers you would get is "user-agent" which includes information about the browser.

It's also good to remember that the IncomingMessage extends the <stream.Readable> class, so each request object is, indeed, a stream.

res: shorthand for "response", is an object from the class ServerResponse, which contains a collection of methods to send back an HTTP response. Some of the methods are:

  • .writeHead() should be called first when initiating a response, allows us to set up the HTTP response code and headers we are sending back.

  • .write(chunk[, encoding][, callback]) allows us to send a chunk of data as part of our response. In this case, we declared in the header the content-type as 'text/plain', so each time we write() the data we pass gets attached as a string of text.

    chunk could be either a buffer or a string, in the case, it is a string the second parameter which is optional, allows us to set the encoding of the data being sent, the default value is 'utf8'.

    The third parameter is a callback function to be executed when the chunk of data has been sent.

    The first call to .write() will send the headers established in .writeHeader() or send the default ones.

  • .end() signalizes the response as complete, MUST be called once per response.

Each time we write response data with .write(), the chunk of data we passed gets immediately flushed to the kernel buffer. If we try to .write() after .end() has been called, we will get the following error:

Error [ERSTREAMWRITAFTEREND]: write after end

Handling POST requests with the http module#

In an HTTP post request, we usually get a body as part of the request. How do we access it using the Node HTTP module?
Remember the request object is an instance of the IncomingMessage class which extends the <stream.Readable> class, in post request we can access the body as a stream of data like this:


You could use an application like Postman, to launch the HTTP request to our application, and you would end up with something like this:

While you are in Postman, be sure that you are firing POST request. You will also need to set the following configuration in order to set the 'content-type' headers as 'application-json'


Creating an HTTPS server#

To handle HTTPS requests, Node.js has the core module https, but first, we need some SSL certificates, for the purpose of this example let's generate some self-signed certificates

In your command line (use GitBash if you are on windows) lets run

Now let's use the HTTPS module to create an HTTP server

The main difference is we now have to read the key files and load them into an options object, that we pass to .createServer() to create our new shiny HTTPS server.

Sending a request using the node HTTP module#

Sometimes we would like to do an HTTP request in order to gather data from a third-party HTTP server. We can achieve this by using the Node HTTP module .request()function.

In the following example, we will be calling the postman-echo API which returns whatever we send them.

But I would suggest instead of using the core HTTP module for sending requests, you use something more sophisticated and user friendly as Axios.
The pros of using something like Axios, is promise abstraction, easier to manage errors on requests, and support for really valuable plugins, like Axios retry.

Use Express don't reinvent the wheel with http.createServer()#

In a lot of situations, we can use a framework like Express to create a server instead of doing directly to the HTTP module.

Install express using npm in your command line


Express will give you a more elegant way to handle all your API routes, handle session data, and will provide you some plugins for authentication, Express is gonna make your life way easier!

Conclusion#

We've been through a lot, within this short post, but with these few examples, you should have a good grasp on the core functionalities of the HTTP Node core module.
It's ideal to understand the inner functionalities of the HTTP module, but for more complex tasks is recommended to use an abstraction library, such as express in the case you are building servers, or Axios in the case you are creating HTTP requests.

Have fun and keep coding!

More Resources#

Check out the documentation of the modules we used in this post:

Getting Help (and Feedback)#

If you have any questions - or want feedback on your post - come join our community Discord. See you there!