[NodeJS] Express source code — Router, Route, Layer

Franky Tse
Analytics Vidhya
Published in
5 min readJun 15, 2020

--

Photo by Fabio Comparelli on Unsplash

I wanna write an article talking about some libraries that I use very often and try to figure out how it work is. To see how well you understand it, I think it can be judged by are you able to explain concepts in your words. This skill worth spending time to practice. Therefore, this article is a kind of practice. Let’s get start.

Article Content

  1. What does Express do?
  2. Understand the file structure of Express
  3. Go Through with an example

What does Express do?

‘Express’ allows you to build a server for receiving requests and sending responses. Also, another essential function is to allow executing specific functions if a certain endpoint is being visited(eg. when the URL is https://mywebsite/get/userInfo, save the IP address to log files…etc).

File Structure of Express

The below image shows the relationship between each file. The arrow side is the dependencies that the file needs to run. For example, router/index.js needs router/router.js and router/layer.js to run. Don’t be scared by such image, we won’t go through all of them, just the essential parts.

Go to node_modules > express > lib to see the source code after install
  • index.js : the entry point of the module
  • express.js: grouping different parts of the application into one object
  • application.js: app level properties and methods
  • router.js: router level properties and methods
  • route.js and layer.js: essential files for completing functionality for router

Go Through

I will take reference from the sample code which is on the official website and name the file testing.js

//testing.js
const express = require('express');
const app = express();
const PORT = 8000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(PORT, () => console.log(`Listening at http://localhost:${PORT}`))

Step 1: Get the instance of express

From the code, the first step is to require('express')and assigning it to a variable. This allows you to get the module.exports object from the related file. In this case, it is actually getting the function createApplication from lib/express.js because that function has been assigned to module.exports.

lib/express.js

Step 2: Use the ‘app’ object

You can execute the function in our testing.js using express(). After procedures in createApplication function, an app object will be returned. It included the methods we need while using Express JS.(eg. app.use… etc). To start using what app bring us, we can move to the next step.

Step 3: Make a new route

Let’s move to the app.get('/', ...) . This makes a new route for the express application. Showing that if endpoint'/' get hit, run the latter function. Actual usage can be if arrived on specific pages, send requests to the backend to get the data. You can see there are 2 parameters. One is the ‘path’. One is the function called ‘handler’.

app.get function declaration

The words in green and the <> sign can be ignored if you are not so familiar with generic. However, some interesting point can be noticed is that there are ... in handlers. It means more than 1 handler can be passed in the function. This involves the middleware concept which we will cover later.

Step 4: Build up the server

From the last line of demonstration code, there is app.listen . This is the step in which the server has been built as this app.listen calls createServer() and monitor if there are any requests by calling server.listen .

Relationship between Router, Route and Layer

You may think there is an app.get function in application.js so that this function can be called. Yes, it is. However, the author used a clever way to avoid declaring a bunch of HTTP verb action functions in application.js. A function methods.forEach(...) has been used. When we use require function, that js file is going to run once. When it comes to methods.forEach() in the runtime, it will set up those bunch of HTTP verb actions function into the app object. Therefore, it can delegate the HTTP verb action function to the router[method] function.

Using debugger to show the function after app.get
function to handle different HTTP verb action

A router has been initialised by the function lazyrouter(). One thing worth mentioning is that there is a router stack(actually an array in JS) for saving routes. After that, the route method in the router will be executed and make a new Route and use a Layer to wrap it. Route also has a stack to store the functions that should be called when matching a specific route.

Therefore, The relationship ofRouter, Route andLayer can be shown as follow:

relationship between Layer, Router, Route

Router stack is inside express application. The bottom one should be app router, maybe other routers on top. In each router, there is a route stack which to store the functions that need to be executed when endpoint gets hit.

Conclusion

We have covered several things in this article. Here are some key takeaways. May be the topic next time will focus on req and res mechanism. If you have any questions or comments, please comment down below or reach me on Twitter(@frankytse_07). See you.

  • The application.js file defines the necessary methods for express application to use.
  • methods.forEach() in application.js delegates the HTTP verb actions (eg. get delete…) to the router and further assigning the router’s handler functions to the route.
  • Router stack used to store routers. Each of the routers has its own route stack to save functions.

--

--

Franky Tse
Analytics Vidhya

Studied marketing in the university but enthusiastic in coding. Therefore choosing to be a programmer. Focusing on web development so far.