Requests, Routing and Middlewares Explained | Guide to NodeJS Basics — Part 1

Charchithowitzer
Fasal Engineering
Published in
8 min readSep 7, 2022

Before getting right into requests, routing and middleware, and whatnot, let’s get a quick understanding of what NodeJs and Express are and how they both are very crucial in your application or website development story.

What is NodeJS?

We all are familiar with our favorite JavaScript (JS), but it’s not just limited to client-side scripting to run in the browser. When it was released in 1990 it was just for client-side scripting. But due to the rise of the web, JS also evolved with it. Till 2009 it was almost impossible to run JavaScript on the server and most of the server-side scripting and logic was written in PHP, ASP.NET, JAVA, RUBY, etc. with PHP as the market leader.

Why it was a BIG deal?

When NodeJs was released, it revolutionized development because now a developer can use a single language throughout the whole stack (backend and front-end). NodeJs is not a programming language but an ‘event-driven non-blocking asynchronous JS run-time’ that allows JavaScript to run on a server.

JS on Node is on steroids, here you have a lot more functionality and features (all the client-side related features are not here (like DOM), but you don’t even need them here anyways) which you can use like file-system, memory management, load-balancing and a lot more.

Node JS be like

So, in short, it is a High-level Single-threaded Interpreted JIT Compiled Prototype based Multi-Paradigm language with a Non-blocking Event loop Concurrency model.

Ok, that’s a lot about Node let’s get forward.

What is ExpressJS

Express is a web framework for JS that runs on the node on the server side. It provides a set of features specifically tailored and maintained for web app development.

Why it is useful?

The biggest advantage of the express framework is the simplification of writing complex code when developing a scaling website or application, which otherwise would have been a lot more difficult to handle if all were written in vanilla NodeJS using inbuilt methods.

It handles complex routing, easier handling of requests, adding middlewares(which we are going to learn), server-side rendering, etc.

Requests and Routing

Whenever we load a website or press a button on the webpage the page sends a request to the server which in turn recognizes the request and responds with the corresponding information.

Let’s see how it’s done.

So, I assume that you already know how to set up a server and run it, I also assume that you have express installed.

Setup the app listener

Suppose now we send a request to a server hosted at my localhost and port 3000, my node file index.js should look like this

Here we are importing the express library which gives us access to all the express features and commands inside this file, also in line three we are running the express function(notice that we are assigning the variable app with express and also running it (see the parenthesis after express).

What the above code does,

Now in line 5, we are assigning a port to our express app, to make it simple think of it as an address inside our machine, so the whole URL to my website will look like http://localhost:3000/ This is where our server is running.

Quickly run this file and you should see the message “Now starting the port”. Now our express app(server) is Up and running.

Request Listener

We will now want to add a request listener to our server script that will listen to the request generated from the webpage and will respond with a corresponding response. Let’s see how

Here in line 5, we are listening to a ‘get’ request which means any request that will come from http://localhost:3000/ will be listened to and responded to here. Go to this link and see what is being displayed on the browser.

Routing

Now let’s add a new route or address to our server. It is as simple as.

image 2

Notice in line 9 we have added a new request route. Just see what happens when we go to the address http://localhost:3000/profile.

We get a different response this time which is on the route /profile in our server. That is the desired behavior, exactly like we wanted. Routes are helpful for enabling websites to have different request listeners for performing different tasks on the server and fetching a corresponding output for each of our requests/routes.

Read about Promises, Async/Await in Javascript,

Middlewares — what is it and how to implement

Finally, we are going to learn about “middlewares”. In simple language, middleware is a function/script/program that is going to run between when you send a request to your browser and when you receive it.

In image 2 functions on lines 5 and 9 are middlewares, because when you send the request to the server both two functions execute and reply with a response to our website.

In line 7 you can see we have used the method app.use() the special thing about the app.use() is that it takes a function as a parameter and executes it for each and every request that we send to the server. Here is a callback for the function myMiddleware that we have defined in line 17.

Now run our script and reload our webpage http://localhost:3000/ on the browser, one more time and see what’s happening.

We see this on our node console.

Aaannnndd. WTH just happened there? Where is our homepage? We will get it back.

Analyzing the code

Now we will analyze our code. So our app.use is successfully calling the function myMiddleware which is reflected in the console, but line 8 is not printing anything into the console which means the route function at line 7 is not getting invoked, and that’s why we can’t see any response. How to get it running then?

You see, the callback function in app.use() accepts 3 arguments namely req,res,next() we are familiar with req and res but what is next()?

now pass the arguments res, res, next to the myMiddleware function, reload the script, and refresh the page. (comment next() for now we will learn about it).

console
browser

This is the output on the webpage as well as the console. So, our middleware has access to the req and res and we are able to send responses from here too. Now uncomment the line executing the function next(), i.e., line 25. Save and execute and refresh the page. Let us see the output.

We get an error,

Now starting the port
This is in the Middleware
I am in the home page route
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:387:5)

This indicates that we actually get into the homepage route: this was not the case before. Now comment on the 23rd line and see the behavior. Save, reload, refresh just like before.

We can see in the console output that our script ran and it executed the myMiddleware() function first and then it moved to the function where we defined our homepage route with the actual response being sent to the website. The error says Cannot set headers after they are sent to the client which means that once the response is already sent we cannot perform any other action, which means we cannot respond to the same request more than once. That is why we commented on the response in the middleware function.

Read about GeoSpatial Location Filtering in Node JS,

How middlewares are useful?

Now suppose we want to do something with our data before sending the response or we want to send a totally another response to the user depending upon the parameters of the request, how can it be performed?

Something amazing with middlewares is that we can access the res,req in them and that allows us to perform any required task.

In line 22 we are checking if the query in the request sent by the client is true, if yes then we are executing the next() (the next middleware i.e the arrow function), if not then send the user a response.

notice here we are also sending a query user=true with the request and if this is true then we are calling the next middleware. Now try it yourself with user=false and see the result (I am leaving it for you to check the result).

Sometimes we would want to send some data from our current middleware to the next executing middleware. As we know that all the middleware have access to the req and res, we can easily bind our data with them before calling the next middleware, let's see how.

In line 25 we are adding another field with the request which is isUserFlag and setting its value as true then we are calling our next middleware where it is being printed in the console. Have a look

Hurray!!, we can see that we actually have access to the isUserFlag inside our homepage route.

So this was it, for now, I hope I was able to explain the concepts to you in a very simple manner. If you have any questions you can comment about that, I will be very happy to address those. In the next article I will talk about different types of middleware, next() and body-parser.

If you are starting with Node JS then you might need to learn SASS as well (in order to scale your application), here’s a great piece on SASS —

--

--