Express Middlewares; What are They Really?
The first thing that threw me off on my path to learning Node.js was the fact that functions in JavaScript are first-class objects. With my little knowledge of programming language like Java, this was a huge thing to take in. I mean, how can you pass a function as an argument to another function and call it a “callBack”? Who does that? It turns out the whole JS community does, and it’s in fact a powerful feature of the language.
Haven been able to wrap my head around this concept, I want to explain it (in simple and straight-forward terms) to other beginners like myself who may still have difficulties with the topic.
We are going to build a simple HTTP server in Node.js using the express framework.
I assume that you have prerequisite knowledge about setting up the Node.js development environment. So, I will just go straight to the topic at hand. But first, let’s get somethings out of the way.
What are Express Middlewares?
I promised you this tutorial is going to be in simple terms, so, in that light; express middlewares are callback functions that can intercept any HTTP request that is made to your express application and modifies the request and/or response parameters. A middleware function has access to the request object(req), the response object(res) and the next middleware function in the request-response cycle of your express application. If these still sound technical to you, fret not, the project we are going to work on will clear all your confusions. I promise.
Now let’s go ahead and create our express application.
Step 1: Setting up the environment
- Create a new project folder at any location on your computer. Call it ‘middleware-example’.
- Open the Command Prompt and ‘cd’ to the folder created in step 1 above.
- Enter the command
npm init -y
. This will initialize the directory as a Node project directory and create thepackage.json
file for us. - This is the only place we will need an internet connection in this project. Make sure you are connected and enter the command
npm install --save express
. This will download the express library into our project and put it innode_modules
folder.
If everything goes well, your Command prompt should look something like this.
Now we are set and ready to get our hands dirty in the coding proper.
Step 2: Building the express app
- Open the project folder in any code editor you are familiar with. I strongly recommend VS Code though. I use VS Code, so, with the
package.json
file opened, my project directory looks like the image below.
- Create a new file in the root of the project directory named
index.js
and open it for editing.
First, we have to import the express library into our index.js
module. In a bid to avoid bringing unnecessary complexity into our project, we are going to stick with ES5 require()
syntax for importing all dependencies.
- Type in the following code in the
index.js
file and then, we walk through it.
const app = require(‘express’)();let personObj = {name: “Tunde Ajagbe”,skinColor: “brown”,height: “1.7m”}app.get(‘/person’, (req, res) => {res.status(200).json(personObj);});const PORT = 5000;app.listen(PORT, console.log(`listening on port: ${PORT}`));
What’s happening here?
- We started by requiring the express library, invoking it on the same line and assigned the returned object to the
app
variable. - Line 3 to 7, we defined a person object(using the object literal syntax) with the shown properties.
- Line 9 to 11; this part is very important to our discussion. Here, we invoked the
get()
method on our express object,app
. This will handle anyget
request sent to the specified path/person
.
The app.get()
method takes, as the first argument, the relative url of the request it is to handle, and a list of middleware function(s) which will handle the request and send the response back to the client, or perform some business logic on the request and/or response object and pass the control to the next middleware function on the stack.
In our example, we only have one anonymous middleware function and it’s the second argument we passed to the app.get()
method. And this function only sets the response status code and then send our personObj
as the body of the response.
Notice that we don’t have the next parameter specified in our anonymous function, this is because this middleware function is the one that terminates the request-response cycle by sending data back to the client through the res
object.
Now, let’s spice things up a little.
Suppose we want to allow only a certain user to be able to access the information about ourpersonObj
, we have to check the incoming request to know who is making the request. To do this, we will require that the headers
property of the req
object must specify a passcode
.
Let’s define another function(middleware) that will perform this validation process.
Type the following code into index.js
file, outside of any other code block:
function validateUser(req, res, next){const ourPasscode = “one-long-char-code”;const { passcode } = req.headers; //using obj destructuringif (passcode === ourPasscode) return next();return res.status(401).json({error:{message: “You are not authorized to view this page”}});}
Now, we pass this new validateUser
function as the second argument to the app.get()
method. So, app.get()
now becomes:
app.get(‘/person’, validateUser, (req, res) => {res.status(200).json(personObj);});
Note that the order in which middleware functions are called is of great importance. We want validateUser
to run before our anonymous arrow function, so validateUser
comes first.
Here, we successfully passed the program control to validateUser()
middleware, which checks if the user has the passcode
. If they do, validateUser
invokes the next()
middleware — which in this case is our anonymous arrow function — which then sends the required data over to the client. But, if the user doesn’t have the correct passcode
, validateUser
terminates the request-response cycle and sends an error object back to the client.
Note that the req
, res
and the next
parameters would be implicitly passed by app.get()
.
To test the code in this tutorial:
cd
to the project directory from the Command prompt and enter the command:node index.js
.- Open Postman and send a
GET
request tolocalhost:5000/person
- To get validation, specify a field in the headers with key
user
and set the value asone-long-char-code
.
This is the power of middleware functions in express applications. You can define your own middleware(s) to handle all kinds of functionalities, as we have done here, but there are also numerous predefined middleware packages that avail you of certain functionalities and you can leverage on them while building your express application. The most commonly used ones I have seen are the ones provided by body-parser
, cookie-parser
and express.Router()
.
I hope you go ahead and experiment with the basics you’ve learned here. And if you have any questions, please don’t hesitate to contact me via my social media handles.
Have any comment or anything you feel is off? Please feel free to let me know in the comment section.
My twitter handle: @MercyTunde
Thank you for staying with me till the end.