Hi! Today we are going to dive into an exciting new topic: Setting up a basic Node.js server. So, the first question that may come to your mind could be — why would we need a server, and what does Node.js have to do with it?
Think of servers as the friendly librarians of the internet. Whenever you need a book (web page), you request it from your librarian (server), and it fetches the book for you. Now, Node.js
, as a powerful JavaScript runtime, allows JavaScript to serve as our friendly librarian, handling thousands of requests in a fast, efficient manner.
Our goal today is simple: by the end of this lesson, you will be able to set up and run your own basic server using Node.js
. Isn't that exciting? Let's get started!
Node.js
is a JavaScript runtime, which means it lets us run JavaScript on our computers, which was previously possible only in a web browser. What makes Node.js
elegant is its event-driven, non-blocking I/O model, which makes it efficient for building fast and scalable server-side applications. So, what does this mean? In simple terms, this model allows Node.js
to handle many tasks simultaneously without waiting for another task to complete, which is extremely useful for real-time applications.
Let's imagine a food delivery application. As there can be many orders coming in at the same time, the event-driven model of Node.js
enables the application to simultaneously process these requests without making the users wait for each order to be processed one after the other.
Meet Express.js, which is a very popular and minimalist framework for Node.js
. Why do we need this when we have Node.js
? Well, if Node.js
is a raw ingredient, Express.js
is a method to cook it into an easy-to-consume dish.
Express.js
streamlines the server creation process that is already feasible with bare Node.js
. It adds various features to our Node.js
, like handling multiple routes with a single line of code and middleware for managing requests.
Before you can start setting up your server, there are a couple of things you need to ensure. You should have Node.js
installed on your computer to run a server. You also need Express.js
, which can be installed using npm
(Node Package Manager). However, on CodeSignal, all these come pre-installed, so you don't need to worry about installation.
Let me show you a little code snippet on how to create an Express
application instance and how to make it listen for connections on a specific port.
JavaScript1// Importing the express module 2const express = require('express'); 3 4// Creating an express application 5const app = express(); 6 7// The app listens on port 3000 for connections 8app.listen(3000, function () { 9 console.log('Your app is listening on port 3000'); 10});
When we run this code in Node.js
, it starts a server on port 3000
of your computer. You might wonder what require('express')
is doing. It's simply importing the express
module.
Middleware functions in Express.js
serve as intermediaries in the request-response cycle, allowing code execution, request/response modification, and request termination. They are executed sequentially and can perform tasks such as logging, authentication, or error handling. Think of middleware as a chain of functions that process incoming requests, one at a time, in a sequential manner.
In this sequence, the req
object represents the HTTP request made by the client, containing details like request headers, parameters, and the body. The server responds with the res
object, which represents the HTTP response that the server will send back to the client.
To summarize, any function that has access to req
and res
can be considered middleware. Here's a simple example to demonstrate this concept:
JavaScript1// Logging middleware 2app.use(function (req, res, next) { 3 console.log(`${req.method} request for '${req.url}'`); 4 next(); // Pass control to the next middleware 5}); 6 7// Route handler for the home page 8app.get('/', function (req, res) { 9 res.send('Hello World!'); 10});
In this example, the logging middleware function logs the details of each incoming request and then passes control to the next middleware function or route handler in the sequence. This step-by-step processing makes middleware a powerful concept in structuring and managing web applications.
As mentioned, the res
object in Express.js represents the HTTP response that an Express application sends when it gets an HTTP request. Here are some common res
functions that you might frequently use:
res.send()
: This function sends a response of various types, such as strings, objects, and arrays. For example:
JavaScript1res.send('Hello World!'); 2res.send({ message: 'Hello World!' });
res.json()
: This function sends a JSON response. Similar to res.send()
, but specifically for JSON data. For example:
JavaScript1res.json({ user: 'John Doe' });
res.status()
: This function sets the HTTP status code for the response. It can be chained with other response methods. For example:
JavaScript1res.status(404).send('Not Found');
res.redirect()
: This function redirects the client to a different URL. For example:
JavaScript1res.redirect('/login');
res.set()
: This function sets HTTP headers on the response. For example:
JavaScript1res.set('Content-Type', 'text/plain');
These functions make it easy to craft a variety of responses to client requests, whether you're sending back simple text, JSON data, HTTP status messages, or even redirecting to other routes.
Time to create our own "Hello World" Express.js
server! First, we'll import the express
module, create an express
app, and make it listen on a specific port. But how will the client communicate with our server? This is done via routes.
A route is simply a path in our application. For instance, in a website URL like 'www.example.com/about', /about
is a route that displays the "About" page of the website.
JavaScript1// Importing the express module 2const express = require('express'); 3 4// Creating an express application 5const app = express(); 6 7// Defining a route for the application’s home page 8app.get('/', function (req, res) { 9 res.send('Hello World!'); 10}); 11 12// Error handling middleware 13app.use(function (err, req, res, next) { 14 console.error(err.stack); 15 res.status(500).send('Something broke!'); 16}); 17 18// The app listens on port 3000 for connections 19app.listen(3000, function () { 20 console.log('Your app is listening on port 3000'); 21});
The app.get
method specifies a callback function that will be invoked whenever there is an HTTP GET request to the homepage of the app (i.e., /
). The req
and res
parameters represent the request and response objects, respectively. We also added basic error handling middleware to catch and handle errors.
With our server ready, let's start it up! Running a Node.js
server is as simple as running a command in your terminal. After navigating to the directory of your server file in the terminal (let's say the file is named server.js
), you just need to run node server.js
. This starts your server, and it starts listening for connections. You can then use your web browser, type in localhost:3000
in the address bar, and bam — you're greeted with the "Hello World!" message we sent from our server!
To interact with our backend routes, we can use a popular library called Axios. Axios is a promise-based HTTP client for the browser and Node.js. It's easy to set up and use for sending requests to our routes. For example, to retrieve all todos, you can use a GET request.
Here's a simple example using Axios to perform a GET request:
JavaScript1const axios = require('axios'); 2 3axios.get('http://localhost:3000/') 4 .then(response => { 5 console.log(response.data); 6 }) 7 .catch(error => { 8 console.error('Error:', error); 9 });
In this example, axios.get
sends a GET request to http://localhost:3000/
. When the request is successful, it logs the response data to the console. If there's an error, it catches and logs the error. This makes it easy to interact with your backend routes and test them during development.
Great job! Today, you've stepped into the world of server-side programming and learned how to set up your own server using Node.js
and the Express.js
framework. You've learned the importance of Node.js
and Express.js
, and you've understood how to create and run a server that listens to a specific port and handles routes, along with basic error handling.
Practicing will help cement your understanding of these basics. In the upcoming practice tasks, you'll get to set up your server, add more routes, and handle different HTTP methods. This practice is essential as it will enable you to master setting up a robust server. Keep it up!