This article has been adapted from lesson 4 of Get Programming with Node.js and covers:

  • Generating a basic web server using Node.js and npm
  • Writing code that processes requests from a browser and sends back a response
  • Running a web server in your browser

You can take 35% off Get Programming with Node.js by entering snwexler into the discount code box at checkout at manning.com.


This article covers some basic functions of the http module, a Node.js library of code used for handling requests over the internet. The tech community raves about Node.js and its use of JavaScript as a server-side language. In this article, you build your first web server. In a few short steps, you convert a couple of lines of JavaScript to an application with which you can communicate on your web browser.

CONSIDER THIS

You’re on your way to building your first web application. Before you deliver a complete application, the cooking community would like to see a simple site with the flexibility to improve and add features in the future. How long do you think it will take you to build a prototype?

With Node.js, you can use the http module to get a web server with sufficient functionality built within hours.

Understanding web servers

Web servers are the foundation of most Node.js web applications. They allow you to load images and HTML web pages to users of your app. Before you get started, I’ll discuss some important web server concepts. After all, the final product will look and feel a lot better if you have clear expectations of the result.

WEB SERVERS AND HTTP

web server is software designed to respond to requests over the internet by loading or processing data. Think of a web server like a bank teller, whose job is to process your request to deposit, withdraw, or view money in your account. Just as the bank teller follows a protocol to ensure that they process your request correctly, web servers follow Hypertext Transfer Protocol (HTTP), a standardized system globally observed for the viewing of web pages and sending of data over the internet.

One way that a client (your computer) and server communicate is through HTTP verbs. These verbs indicate what type of request is being made, such as whether the user is trying to load a new web page or updating information in their profile page. The context of a user’s interaction with an application is an important part of the request-response cycle.

Here are the two most widely used HTTP methods you’ll encounter:

  • GET—This method requests information from a server. Typically, a server responds with content that you can view back on your browser (such as by clicking a link to see the home page of a site).
  • POST—This method sends information to the server. A server may respond with an HTML page or redirect you to another page in the application after processing your data (such as filling out and submitting a sign-up form).

I discuss a couple more methods in the book in lesson 18.

Most web applications have made changes to adopt HTTP Secure (HTTPS), in which transmission of data is encrypted. When your application is live on the internet, you’ll want to create a public key certificate signed by a trusted issuer of digital certificates. This key resides on your server and allows for encrypted communication with your client. Organizations such as https://letsencrypt.org offer free certificates that must be renewed every 90 days. For more information about HTTPS, read the article at https://developers.google.com/web/fundamentals/security/encrypt-in-transit/why-https.

When you visit https://www.google.com, for example, behind the scenes you’re making a request to Google’s servers, which in turn send a response back to you, rendering the famous Google Search landing page. This request-response relationship allows for a channel of communication between the user and the application. In figure 1, a bundle of data is sent to the application’s server in the form of a request, and when the server processes the request, it issues a bundle of data back in the form of a response. This process is how most of your interaction on the internet is facilitated.


Figure 1. A web server sends your browser web pages, images, and other resources on request.


When you enter the URL you want to see in your browser, an HTTP request is sent to a physical computer elsewhere. This request contains some information indicating whether you want to load a web page or send information to that computer.

You may build a fancy application with many bells and whistles, but at the core lies a web server to handle its communication on the internet. In the next section, you start building your web server.

QUICK CHECK 1

Q1:

What does a web server receive from the client, and what does it send back?

QC 1 ANSWER

1:

The web server receives requests from the client and sends back responses.

Initializing the application with npm

Before you get started with a Node.js web application, you need to initialize the project in your project folder in terminal. Open a terminal window, and create a new directory called simple_server with mkdir. You can initialize the project with npm init.

NOTE:  npm is Node.js’ package manager. Your Node.js projects rely on this tool to install and build applications. You can learn more about npm and how it’s used at https://docs.npmjs.com.

Running the npm init command initiates a prompt to create a package.json file. As the prompt explains, you’ll walk through configuring the most basic settings of your Node.js application in this file. For now, you can add main.js as the entry point, along with a short description and your name as the author, and elect to use the default values offered by pressing the Enter key until you reach the end of the prompt

Then you’re asked to confirm your settings with a preview of your package.json file. Press Enter to confirm and return to the regular terminal prompt.

Coding the application

When you installed Node.js, the core library was installed too. Within that library is a module called http. You’ll use this module to build your web server. In this section, you also use a package called http-status-codes to provide constants for use where HTTP status codes are needed in your application’s responses.

NOTE:  Modules in Node.js are libraries of code that come packaged to offer specific functionality to your application. Here, the http module helps you communicate across the web by using HTTP.

In your text editor, create a new file called main.js, and save it in the project folder called simple_server containing the package.json file you created earlier. This file will serve as the core application file, where your application will serve web pages to your users. Within this project’s directory in terminal, run npm i http-status-codes -S to save the http-status-codes package as an application dependency.

Before I analyze every aspect of what you’re about to build, take a look at all the code in listing 1. The first line of code assigns the port number you’ll use for this application: 3000.

NOTE:  Port 3000 is generally used for web servers in development. This number has no significance, and you can customize it with a few exceptions. Ports 80 and 443 usually are reserved for HTTP and HTTPS, respectively.

Then you use require to import a specific Node.js module called http and save it as a constant. This module is saved as a constant because you don’t plan on reassigning the variable. You also require the http-status-codes package to provide constants representing HTTP status codes.

Next, you use the http variable as a reference to the HTTP module to create a server, using that module’s createServer function, and store the resulting server in a variable called app.

NOTE:  Using ES6 syntax, you structure callback functions with parameters in parentheses, followed by instead of the function keyword.

The createServer function generates a new instance of http.Server, a built-in Node.js class with tools for evaluating HTTP communication. With this newly created server instance, your app is prepared to receive HTTP requests and send HTTP responses.

WARNING:  These method names are case-sensitive. Using createserver, for example, will throw an error.

The argument in createServer is a callback function that’s invoked whenever some event occurs within the server. When the server is running and your application’s root URL (home page) is accessed, for example, an HTTP request event triggers this callback and allows you to run some custom code. In this case, the server returns a simple HTML response.

You log that a request was received from the client and use the response parameter in the callback function to send content back to the user, from whom you first received a request. The first line uses a writeHead method to define some basic properties of the response’s HTTP header. HTTP headers contain fields of information that describe the content being transferred in a request or response. Header fields may contain dates, tokens, information about the origins of the request and response, and data describing the type of connection.

In this case, you’re returning httpStatus.OK, which represents a 200 response code, and an HTML content-type to indicate that the server received a request successfully and will return content in the form of HTML. Following this block, you assign a local variable, responseMessage, with your response message in HTML.

NOTE:  200 is the HTTP status code for OK, used to indicate that no issue occurred in returning content in an HTTP response header. To get a list of other HTTP status codes, enter http.STATUS_CODES in the Node.js REPL shell. Use httpStatus.OK in place of the explicit number.

Right below that line, you’re writing a line of HTML in the response with write and closing the response with end. You must end your response with end to tell the server that you’re no longer writing content. Not doing so leaves the connection with the client open, preventing the client from receiving the response. You also log your response at this point so you can see that a response was sent from the server itself.

The last line of code takes the server instance, app, and runs the listen method to indicate that the server is ready for incoming requests at port 3000.

Listing 1. Simple web application code in main.js

 
 const port = 3000,
   http = require("http"),                                              1
   httpStatus = require("http-status-codes"),
   app = http.createServer((request, response) => {                     2
     console.log("Received an incoming request!");
     response.writeHead(httpStatus.OK, {
       "Content-Type": "text/html"
     });                                                                3
  
     let responseMessage = "<h1>Hello, Universe!</h1>";
     response.write(responseMessage);
     response.end();
     console.log(`Sent a response : ${responseMessage}`);
   });
  
 app.listen(port);                                                      4
 console.log(`The server has started and is listening on port number:
 ${port}`);
  

1 Require the http and http-status-codes modules.

2 Create the server with request and response parameters.

3 Write the response to the client.

4 Tell the application server to listen on port 3000.

NOTE: The response object is used by Node.js and carried throughout the application as a way to pass information about the current client transaction from function to function. Some methods on the response object allow you to add data to or remove data from the object; writeHead and write are two such functions.

There your application is, in all its glory! Not so terrible. In only a few lines of code, you’ll also build a web server this way.

NOTE: If you don’t specify a port number, your operating system will choose a port for you. This port number is what you’ll soon use to confirm through your web browser that your web server is running.

CALLBACKS IN NODE.JS

Part of what makes Node.js so fast and efficient is its use of callbacks. Callbacks aren’t new to JavaScript, but they’re overwhelmingly used throughout Node.js and worth mentioning here.

callback is an anonymous function (a function without a name) that’s set up to be invoked as soon as another function completes. The benefit of using callbacks is that you don’t have to wait for the original function to complete processing before running other code.

Consider virtually depositing a check in your bank account by uploading a picture to your bank’s mobile app. A callback is equivalent to receiving a notification a couple of days later that the check was verified and deposited. In the meantime, you were able to go about your normal routine.

In the http web server example, incoming requests from the client are received on a rolling basis and thereupon pass the request and response as JavaScript objects to a call-back function, as shown in the following figure:



Callbacks on the server indicate when to respond to the client.

With this code in place, you’re ready to start your Node.js application from terminal.

QUICK CHECK 2

Q1:

Why should you use const instead of var to store the HTTP server in your application?

QC 2 ANSWER

1:

Because your server will continue to listen for communication from clients, it’s important not to reassign the variable representing the server. In ES6, it has become convention to mark these objects as constants, not reassignable variables.

Running the application

The last step is an easy one. Navigate to your project’s directory with terminal, and run node main in your terminal window. Next, open any browser to the address localhost: 3000. You see a message indicating that the server has started. Your terminal window should resemble figure 2.


Figure 2. Running the a basic Node.js server


The browser window should greet you and the universe with salutations, as shown in figure 3. Congratulations! Your first Node.js web application is complete. It’s big, and it’s about to get bigger and better.


Figure 3. Display of your first web page


To stop the application, press Ctrl-C in your terminal window. You can also close the terminal window, but you may risk not shutting down the application properly, in which case the application could continue to run behind the scenes (requiring more command-line magic to kill the process).

QUICK CHECK 3

Q1:

When you navigate to http://localhost:3000/ while your server is running, what type of HTTP request are you making?

QC 3 ANSWER

1:

Nearly every request you can expect to make at this stage in the application’s development, including a request to http://localhost:300/, is an HTTP GET request.

Summary

In this article, you learned that Node.js has built-in functionality for creating web servers via the http module. You configured a new Node.js application via the package.json file. Using the http module and createServer method, with minimal effort you created a web server, which is a stepping stone to building robust applications with Node.js. Through terminal, you were able to run a web-server application.

Complete the “Try this” exercise to check your understanding.

TRY THIS

npm init interactively generates a package.json file, although you could create this file on your own.

Create a new package.json from scratch for the project in this lesson. Don’t use npm init; see whether you can construct a similar JSON-structured file.

That’s all for now. If you want to learn more about the book, you can check it out on Manning’s browser-based liveBook platform here.