beginner

Routes


We’ve created a server but how can we start returning different responses for different requests? For that we will use routes.

Url and Parts of Url

Routes refer to the paths or endpoints of a web application that are used to map specific URLs to particular functionalities or content. To understand this we first need to understand what is an url and all of its different parts. Parts of url are explained in picture below:

Parts of url

image courtesy of https://www.geeksforgeeks.org/

Extending Our Server Code

Let’s extend our existing server code and introduce routes.

const http = require("http");

// Create a simple router function
function router(req, res) {
  const protocol = req.protocol ?? "http";
  const baseUrl = `${protocol}://${req.headers.host}/`;
  console.log(baseUrl); // http://localhost:3000/
  const reqUrl = new URL(req.url, baseUrl);
  console.log(reqUrl); // URL object
  const path = reqUrl.pathname;
  console.log(path); // /about (if we go to url http://localhost:3000/about)

  // Define routes
  if (path === "/") {
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end("Welcome to the Home Page!");
  } else if (path === "/about") {
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end("This is the About Page!");
  } else {
    res.writeHead(404, { "Content-Type": "text/plain" });
    res.end("404 Not Found");
  }
}

// Create an HTTP server and pass the router function to handle requests
const server = http.createServer(router);

// Set the server to listen on port 3000
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

Understanding the Code

Given a complete url of https://mariodoesdev.com/posts/routes-nodejs/ we want to get /posts/routes-nodejs/. We first access protocol property of a req object and sometimes(in local development) it can be undefined so we will use nullish coalescing operator(??) to return http if it is undefined. Then we want to use protocol and req.headers.host to create baseUrl using template literals. Then we instantiate new URL object by passing in req.url(this is actually path /posts/routes-nodejs/ and not the entire url) and baseUrl. The reason we are doing this when we already have path from req.url is that we need to parse the path to remove any undesired characters(because urls follow strict rules on what characters are allowed in what part of url). After all of that, we access the path with reqUrl.pathname

const protocol = req.protocol ?? "http";
const baseUrl = `${protocol}://${req.headers.host}/`;
const reqUrl = new URL(req.url, baseUrl);
const path = reqUrl.pathname;

Now that we have our path, we can use if else statements to send a specific response based on our path. If we find our path we send back status code 200 and response message but if we can’t match our path then we will return status code 404 meaning resource not found.

For all of this to work, we need to pass our router function as a parameter when we create our server.

const server = http.createServer(router);

What Now?

With all of this, we can return different responses for different routes. Try:

http://localhost:3000/ -> will return 200 and Welcome to the Home Page! http://localhost:3000/about -> will return 200 and This is the About Page! http://localhost:3000/something -> will return 404

Create your own routes. You will see how after a while, a simple if else is not enough. In the next post we are going to slightly improve this.

Previous Creating server
Next HTTP request methods | Events and streams