Node.js Webserver with HTTP Module is so easy!

Node.js Webserver with HTTP Module is so easy!

No framework. No third-party modules.

Β·

5 min read

What if your car breaks down on a highway and you have no clue what the mechanic is saying about the problem?

This is the same as working with your Node.js webserver using frameworks such as Express. You know how to build applications. But you don't know how those applications work.

And that's usually fine until you find a need to leverage the platform more efficiently.

There are many easy ways to build a webserver by using frameworks such as Express. However, it is also not that hard to build a basic Node.js Webserver with the core HTTP module and nothing else. Even if you might not use it to build real applications, knowing how it's done has benefits if you want to become a real Node.js practitioner. Just like being an automobile enthusiast instead of a simple driver.

Surely, you don't want to be just a driver!

All right - so now that you are convinced, let's build an extremely simple webserver in Node.js.

Node.js Basic Webserver

Create a file named index.mjs in a project directory and paste the below code into the file.

import { createServer } from "http";

const server = createServer();
server.listen(8080, () => {
    console.log(`Server is listening to http://localhost:${server.address().port}`);
});

And that's all the code that is needed to create a Node.js webserver.

  • We import createServer() function from the http module. This is a core module that ships with the Node.js installation.

  • Next, we call the createServer() function to get a server object. We store the object in a constant named server.

  • The server object has a method named listen() that takes a couple of arguments. One is the port number and the second is a callback function that prints a message when the server is ready to handle requests.

To start the server, we can use the command node index.mjs.

Of course, saying that this server is useless would be an understatement. When you visit http://localhost:8080, nothing happens. If you are lucky, you might get a timeout.

Even though the server is up and running, it does not know what to do with an incoming request.

Handling HTTP requests with Node.js Webserver

How do we make the server somewhat useful?

We give it the ability to handle requests. Check out the below code:

import { createServer } from "http";

const server = createServer((request, response) => {
    response.writeHead(200, {'content-type': 'text/plain; charset=utf-8' })
    response.write('Hello');
    response.end(' World\n');
});

server.listen(8080, () => {
    console.log(`Server is listening to http://localhost:${server.address().port}`);
});

The createServer() function now takes a callback with two input objects - request and response. The callback will handle every incoming request.

The response object helps us manipulate the output. The writeHead() method is used to set the response status code (200) and response headers. For example, we set the content-type to text/plain and charset to utf-8.

Next, we use response.write() method to set the actual response string. You can have multiple response.write() statements one after the other.

Once we are finished with the response, we need to tell the webserver to close the stream. This is done using response.end() method. The response.end() function can also take some part of the response.

But who uses a webserver to send some text response? Of course, there might be a requirement but it does not seem like the best use of a webserver.

How about sending some HTML as a response?

HTML Response using Node.js Webserver

See the below code:

import { createServer } from "http";

const server = createServer((request, response) => {
    response.writeHead(200, {'content-type': 'text/html; charset=utf-8' })

    const body = `<!DOCTYPE html>
        <html>
            <head>
                <meta charset="utf-8">
                <title>Node.js Webserver Demo</title>
            </head>
            <body>
                <h1 style="color: orange">Hello World</h1>
            </body>
        </html>`;

    response.end(body);
});
server.listen(8080, () => {
    console.log(`Server is listening to http://localhost:${server.address().port}`);
});

Despite the size of the code, there are only minor modifications.

One is setting the content-type value to text/html. The second is declaring a constant named body with some HTML content and sending it as part of response.end() function call.

If you access http://localhost:8080 now, you should see the HTML page displayed in the browser.

At this point, you might feel somewhat satisfied with the capabilities of the Node.js webserver. But the nature of the content is still pretty static.

Typical web applications consist of dynamic web pages. Content depends on the request made by the user.

How can our Node.js webserver generate dynamic responses?

Dynamic Response with Node.js Webserver

The changes are pretty straightforward. See below:

import { createServer } from "http";

const server = createServer((request, response) => {
    response.writeHead(200, {'content-type': 'text/html; charset=utf-8' })

    const url = new URL(request.url, 'http://localhost:8080');

    const body = `<!DOCTYPE html>
        <html>
            <head>
                <meta charset="utf-8">
                <title>Node.js Webserver Demo</title>
            </head>
            <body>
                <h1 style="color: orange">Hello ${url.searchParams.get('name')}</h1>
            </body>
        </html>`;

    response.end(body);
});
server.listen(8080, () => {
    console.log(`Server is listening to http://localhost:${server.address().port}`);
});

The major change in the above snippet is that we read the URL requested by the client using the request.url property. For example, if the user enters the URL http://localhost:8080/?name=progressivecoder in the address bar of the browser, the request.url will contain the value /?name=progressivecoder.

Since we want to display the name in the HTML response, we use the WHATWG URL API to create a URL instance. The URL API enables us to parse URLs and break them into individual components. It will produce an object that represents the requested URL with all of the components.

Within the HTML string, we extract the query parameter name from the URL object's searchParams property.

If you access http://localhost:8080/?name=progressivecoder after making the above change, you will see Hello progressivecoder displayed in the browser window. This is a dynamic HTML output that depends on what we pass in the request's query parameters.

Concluding Thoughts

There is no doubt using a framework makes life easy for developers. You ultimately write less code and focus more on business logic. Also, you write less boilerplate code to handle basic things when using a framework.

But knowing how things work under the hood of any framework is also important. Learning how to create a Node.js webserver with just the core HTTP module gives you important lessons on how the frameworks work internally.


If you enjoyed this article or found it helpful, let's connect. Please hit the Subscribe button at the top of the page to get an email notification about my latest posts.

You can also connect with me on other platforms:

Twitter

LinkedIn

Youtube

Did you find this article valuable?

Support Saurabh Dashora by becoming a sponsor. Any amount is appreciated!

Β