Click to share! ⬇️

Node.js is a popular open-source, cross-platform runtime environment used for building server-side applications. It is built on top of Google’s V8 JavaScript engine and provides a runtime environment for executing JavaScript code outside the browser. Node.js allows developers to build scalable, high-performance applications using JavaScript on the server-side. It is known for its event-driven, non-blocking I/O model, which enables it to handle large amounts of data with ease.

Node.js is used by many major companies, including Netflix, PayPal, and LinkedIn, and has a vast and growing community of developers. In this tutorial, we will walk through the process of creating a simple server using Node.js.

Setting up the Environment

Before we can start building our Node.js server, we need to set up our development environment.

  1. First, we need to download and install Node.js. You can download the latest version of Node.js from the official Node.js website.
  2. Once Node.js is installed, we can check that it is installed correctly by opening a terminal or command prompt and running the command node -v. This should print out the version of Node.js installed on your machine.
  3. Next, we need to create a new folder for our project. Open a terminal or command prompt and navigate to the directory where you want to create your project folder. Then run the command mkdir my-project to create a new folder called “my-project”.
  4. Navigate into the new folder by running the command cd my-project.
  5. Now we need to create a new file for our server code. You can create a new file called server.js by running the command touch server.js.

With our development environment set up and our project folder created, we can start building our Node.js server in the server.js file.

Creating the Server File

Now that we have set up our development environment, it’s time to start building our Node.js server.

  1. Open the server.js file in your text editor of choice.
  2. The first thing we need to do is import the required modules. In Node.js, modules are used to group related code together. We will be using the http module to create our server, so we need to import it by adding the following code at the top of our server.js file:
const http = require('http');
  1. Next, we need to create a server. We can create a server by calling the createServer method of the http module and passing in a function that will be called whenever the server receives a request. This function is known as the request handler. Add the following code below the module import:
const server = http.createServer((req, res) => {
  // request handling logic goes here
});
  1. Inside the request handler function, we will add the logic for handling the incoming request and sending a response back to the client. For now, we will simply send a plain text response with the message “Hello, world!”. Add the following code inside the request handler function:
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, world!');
  1. Finally, we need to tell our server to start listening for incoming requests. We can do this by calling the listen method of the server object and passing in a port number. For example, we can listen on port 3000 by adding the following code at the end of our file:
server.listen(3000, () => {
  console.log('Server is listening on port 3000');
});

This will start our Node.js server and log a message to the console indicating that the server is running. We can now test our server by opening a web browser and navigating to http://localhost:3000. If everything is set up correctly, we should see the message “Hello, world!” displayed in the browser.

Installing Dependencies

Our Node.js server is currently only able to respond with a simple text message. To make it more useful and flexible, we can install some external packages, or dependencies, that will provide additional functionality.

In this example, we will install the express package, which is a popular Node.js web framework that provides a wide range of features for building web applications.

  1. To install express, open a terminal or command prompt and navigate to your project directory.
  2. Run the command npm init to create a new package.json file for your project. This file will contain information about your project and the dependencies it uses.
  3. Follow the prompts to set up your package.json file. You can accept the defaults for most of the options, but you will need to specify a name, version, and description for your project.
  4. Once your package.json file is set up, you can install the express package by running the command npm install express.
  5. This will download and install the express package and its dependencies in a new folder called node_modules in your project directory. It will also update your package.json file to include express in the list of dependencies.

With express installed, we can now modify our server.js file to use it instead of the built-in http module.

Configuring the Server

Now that we have installed the express package, we can modify our server.js file to use it instead of the built-in http module. We will also configure our server to handle requests more flexibly and securely.

  1. Replace the http module import with the express module import at the top of your server.js file:
const express = require('express');
  1. Replace the server creation code with the following:
const app = express();

app.listen(3000, () => {
  console.log('Server is listening on port 3000');
});

This creates a new express application and starts it listening on port 3000. We will add more configuration to the application object in the next steps.

  1. We can use express middleware to add additional functionality to our server. Middleware functions are functions that have access to the request and response objects and can perform actions based on them. We will use the express.json() middleware function to parse JSON data from requests, and the express.static() middleware function to serve static files from a public directory. Add the following code before the app.listen() call:
app.use(express.json());
app.use(express.static('public'));

This tells our express application to use the express.json() middleware for all incoming requests, and to serve files from the public directory for all static file requests.

  1. We can also define routes for our server using the express routing system. Routes are used to handle requests to specific URLs and HTTP methods. For example, we can define a route to handle GET requests to the URL /hello by adding the following code after the middleware definitions:
app.get('/hello', (req, res) => {
  res.send('Hello, world!');
});

This tells our express application to respond with the message “Hello, world!” whenever a GET request is made to the URL /hello.

With these configurations in place, we now have a much more flexible and secure server that can handle a variety of requests and data types.

Defining the Routes

Routes in express are used to handle incoming requests to specific URLs and HTTP methods. In this section, we will define routes for our server to handle various types of requests.

  1. First, let’s modify our existing /hello route to accept a query parameter and respond with a personalized message. Replace the existing /hello route code with the following:
app.get('/hello', (req, res) => {
  const name = req.query.name || 'world';
  res.send(`Hello, ${name}!`);
});

This tells our express application to respond with a personalized message based on the name query parameter, or “world” if the parameter is not provided.

  1. Next, let’s define a route to handle POST requests to the /api/messages URL. This route will accept a JSON object in the request body and return a JSON object with a success message. Add the following code after the /hello route:
app.post('/api/messages', (req, res) => {
  const { message } = req.body;
  if (!message) {
    return res.status(400).json({ error: 'Message is required' });
  }
  res.json({ success: true, message });
});

This tells our express application to handle POST requests to the /api/messages URL, extract the message field from the request body, and respond with a JSON object containing a success message and the original message.

If the request body does not contain a message field, the route will respond with a 400 Bad Request error and a JSON object containing an error message.

  1. Finally, let’s define a route to serve an HTML file for all other requests to our server. We will create a new file called index.html in a new views directory and serve it using the express res.sendFile() method.

First, create a new directory called views in your project directory, and inside it create a file called index.html with the following code:

<!DOCTYPE html>
<html>
<head>
  <title>My Server</title>
</head>
<body>
  <h1>Welcome to my server!</h1>
</body>
</html>

Then, add the following code at the end of your server.js file:

app.use((req, res) => {
  res.sendFile(__dirname + '/views/index.html');
});

This tells our express application to serve the index.html file for all requests that do not match any of our previous routes.

With these routes defined, our express application is now capable of handling a variety of requests and responding with different types of data.

Handling Requests and Responses

In express, requests and responses are represented by objects that contain a variety of properties and methods for handling incoming data and sending responses back to clients.

  1. Request Object

The req object represents the incoming request to our server and contains a variety of properties and methods for accessing the request data. Some of the most commonly used properties include:

  • req.params: an object containing the named route parameters for the request
  • req.query: an object containing the query parameters for the request
  • req.body: an object containing the parsed request body data (for POST, PUT, and PATCH requests)
  • req.cookies: an object containing any cookies sent with the request
  • req.headers: an object containing the HTTP headers sent with the request
  1. Response Object

The res object represents the outgoing response from our server and contains a variety of methods for sending data back to clients. Some of the most commonly used methods include:

  • res.send(): sends a response with the given data and automatically sets the appropriate headers based on the data type
  • res.json(): sends a response with a JSON object and automatically sets the Content-Type header to application/json
  • res.status(): sets the HTTP status code for the response
  • res.cookie(): sets a cookie on the response
  • res.redirect(): sends a redirect response to the client
  1. Middleware

In express, middleware functions are functions that have access to the req and res objects, and can modify them or perform additional actions based on them. Middleware functions are used to add additional functionality to our server, such as authentication, logging, and error handling.

Middleware functions can be added to our express application using the app.use() method. Middleware functions can be defined with a single function argument, or with multiple arguments representing a chain of middleware functions.

For example, we can define a middleware function to log all incoming requests to our server by adding the following code to our server.js file:

app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

This tells our express application to log the request method and URL to the console for all incoming requests, and then pass the request to the next middleware function.

With these tools and concepts in mind, we can now build more complex and flexible servers in express.

Running the Server

To run our express server, we simply need to run the node command with the name of our server.js file as the argument.

  1. Open a terminal or command prompt and navigate to your project directory.
  2. Run the command node server.js to start your server.
  3. If everything is set up correctly, you should see a message in the console indicating that the server is running, and you can access it by navigating to http://localhost:3000 in a web browser.
  4. You can stop the server at any time by pressing Ctrl+C in the terminal or command prompt.

By default, express servers listen on port 3000, but you can change the port number by modifying the app.listen() call in your server.js file. For example, you can change the port number to 8080 by changing the app.listen() call to the following:

app.listen(8080, () => {
  console.log('Server is listening on port 8080');
});

You can then access your server by navigating to http://localhost:8080 in a web browser.

Testing the Server

Testing is an important part of building any software project, and express makes it easy to write automated tests for our server using various testing frameworks and libraries.

In this section, we will briefly discuss some of the testing options available for express.

  1. Manual Testing

The simplest way to test our express server is to manually send requests to it using a web browser or a tool like curl. We can test each of our routes by sending requests with different parameters and data, and verifying that the responses are correct.

For example, we can test our /hello route by navigating to http://localhost:3000/hello?name=John in a web browser and verifying that the response contains the message “Hello, John!”.

  1. Integration Testing

Integration testing involves testing our server as a whole, by sending requests to it and verifying the responses using automated testing frameworks like Jest or Mocha.

For example, we can use the supertest library to write integration tests for our express server. Here’s an example test that tests our /hello route:

const request = require('supertest');
const app = require('./server'); // import our express app

describe('GET /hello', () => {
  it('responds with "Hello, world!" when no name is provided', (done) => {
    request(app)
      .get('/hello')
      .expect(200)
      .expect('Hello, world!', done);
  });

  it('responds with a personalized message when a name is provided', (done) => {
    request(app)
      .get('/hello?name=John')
      .expect(200)
      .expect('Hello, John!', done);
  });
});

This test uses supertest to send GET requests to our /hello route with and without a name parameter, and verifies that the response contains the correct message.

  1. Unit Testing

Unit testing involves testing individual components of our server, such as routes, middleware functions, or other modules, in isolation from the rest of the server using testing frameworks like Jest, Mocha, or Jasmine.

For example, we can use the Jest testing framework to write unit tests for our /api/messages route. Here’s an example test that tests the route’s response to different request bodies:

const request = require('supertest');
const app = require('./server'); // import our express app

describe('POST /api/messages', () => {
  it('responds with a success message when a message is provided', async () => {
    const response = await request(app)
      .post('/api/messages')
      .send({ message: 'Hello, world!' });
    expect(response.status).toBe(200);
    expect(response.body).toEqual({ success: true, message: 'Hello, world!' });
  });

  it('responds with a 400 error when no message is provided', async () => {
    const response = await request(app)
      .post('/api/messages')
      .send({});
    expect(response.status).toBe(400);
    expect(response.body).toEqual({ error: 'Message is required' });
  });
});

This test uses supertest to send POST requests to our /api/messages route with and without a message field in the request body, and verifies that the response contains the correct status code and data.

With these testing options available, we can ensure that our express server is working correctly and reliably, and catch and fix any bugs or issues before they reach production.

Creating a Simple Server with Node.js FAQ

Q: What is Node.js?

A: Node.js is a JavaScript runtime built on the V8 JavaScript engine that allows developers to run JavaScript code outside of a web browser. It is often used to build server-side applications and web services.

Q: Why use Node.js for server-side development?

A: Node.js provides several advantages over traditional server-side technologies like PHP, Java, or Ruby. Some of these advantages include:

  • Fast and efficient performance due to its non-blocking I/O model
  • Easy scalability and support for large-scale applications
  • Ability to use the same language (JavaScript) on both the front-end and back-end of a web application
  • Large and active community of developers and resources

Q: What is express?

A: express is a popular web application framework for Node.js that provides a wide range of features for building web services and APIs. It is built on top of the built-in http module and provides a more flexible and secure way to handle requests and responses.

Q: What is middleware in express?

A: Middleware in express is a function that has access to the req and res objects, and can perform additional actions based on them. Middleware functions are used to add additional functionality to our server, such as authentication, logging, and error handling.

Q: How do I run an express server?

A: To run an express server, you simply need to run the node command with the name of your server.js file as the argument. For example, if your server file is called server.js, you can run it by typing node server.js in a terminal or command prompt.

Q: How do I test my express server?

A: There are several ways to test an express server, including manual testing, integration testing using automated testing frameworks like Jest or Mocha, and unit testing individual components of the server using testing frameworks like Jest, Mocha, or Jasmine.

Click to share! ⬇️