Stop playing the role of the client. It’s time to switch sides. In this lesson, we break out of the browser and step into the backend. You’re going to learn how to stand up a Node.js server using Express, open a network port, and actively listen for incoming requests.
1The Engine and The Framework
Up until now, you've used tools like fetch() or Postman to request data from external APIs. You were the client. Now, you are building the server that receives those requests.
A server is simply a computer connected to the internet that runs 24/7, waiting for incoming network traffic. To build ours, we use Node.js. Node.js is a runtime environment written in C++ that extracts the V8 JavaScript engine from Google Chrome, allowing JavaScript to run directly on a computer's operating system. This is what gives JavaScript the power to access the file system and open network ports.
While you can build a server using raw Node.js, doing so requires writing hundreds of lines of complex networking code. This is why we use Express.js. Express is a minimalist, unopinionated web framework built on top of Node. It abstracts away the low-level HTTP protocols, allowing you to initialize a robust server in just three lines of code.
async function execute() {
// See concept above
}
2Opening the Port
To create an Express server, you import the library, initialize an app object, and tell that app to listen on a specific port.
const express = require('express');
const app = express();
app.listen(3000, () => {
console.log("Server running on port 3000");
});A single server computer can run multiple applications simultaneously. It differentiates traffic using Ports—logical endpoints numbered from 0 to 65535. Standard, unencrypted web traffic always goes to port 80, while secure HTTPS traffic goes to port 443. When developing locally, we typically configure our Express app to listen on port 3000 or 8080.
The app.listen() command is crucial. It hooks into the operating system and initializes an infinite loop that keeps the Node.js process alive, actively listening for incoming HTTP requests on that specific door.
async function execute() {
// See concept above
}
3Routing: The API Map
Once the server is listening, it needs instructions on what to do when a request arrives. This is known as Routing.
You define a route by mapping an HTTP Method (like GET, POST, DELETE) to a specific URL path (like /api/users). When a client's request matches that exact combination of method and path, Express triggers a Callback Function that you provide.
app.get('/welcome', (req, res) => {
// Route matched! Execute this logic.
});This callback function acts as the controller. It is where you write the business logic to query the database, validate input, and decide what data to return.
async function execute() {
// See concept above
}
4The Request/Response Cycle
Every Express route callback function is automatically injected with two critical objects: req (the Request) and res (the Response).
The `req` object contains everything the client sent you. If the client sent a JSON payload, you find it in req.body. If they sent an authorization token, it's in req.headers. If they included dynamic URL variables, they are in req.params.
The `res` object provides the tools you need to close the cycle and send data back. You use methods like res.status(200) to set the HTTP status code, and res.json() to format and transmit your data payload.
app.get('/profile', (req, res) => {
const token = req.headers.authorization;
// ... verify token ...
res.status(200).json({ user: "Alice" });
});Critical Rule: You must always close the request/response cycle. If you execute your database logic but forget to call res.json() or res.send(), the client's browser will spin indefinitely, waiting for a response that will never arrive, until it eventually times out.
async function execute() {
// See concept above
}
