Learn Express.js: Middleware Functions + Mario Bros.👨‍🔧🍄 🐢

Sam Lesser
7 min readApr 18, 2021
Where do these pipes go? 🧐 🤔 🤨
Hey there fellow reader,If you plan on reading this blog, you’ll need to know a few things first. I encourage you to read some of my blogs further explaining these topics. It’s totally worth your time! Remember understanding the Basics and the lingo is key. Don’t sweat the small stuff.Here’s the rub…- Basics Node.js- Basic understanding of how Servers/back-end works- Basic understanding Request/Response Cycles- The concept of Abstraction(Computer Science)- Basic understanding of Frameworks- Basic Understanding of Javascript Syntax (ES6)- FYI I like to use Mac OS + VSCODE,but feel free to use what you like !

Introduction

Let’s see where this pipe goes…

Hey everyone, This week I was tearing into learning the Node.js + Express.js combo. I’d like to focus on a really important abstraction of this web framework which is the middleware functions as they are a fundamental feature offered by Express.js.

If you’re wondering what exactly a web framework is and why we use it. Please check out my blog which will dive further into Express.js and Web frameworks. It’s a fun read and worth taking a peek at.

Confused or Need a refresher? Give these links a try! 🙋‍♀️ 🙋‍♂️ 🙋Node.js: https://ineedmoreplates.medium.com/learning-node-js-8288e0411957Setting up a Node Server: https://ineedmoreplates.medium.com/node-js-setting-up-a-server-534d86658252Express.js: https://ineedmoreplates.medium.com/express-js-learn-with-p-e-memes-bfa080b5a918

What’s Middleware?

Seriously, what is middleware? is it like an API or something? 🤨

Let’s start with an obvious question. What exactly is middleware? If you poke around the internet or do a little “google-fu” you’ll quickly realize Middleware does a lot for its users. Being that its third-party software can cover a vast number of use cases depending upon what you are trying to accomplish as a developer.

Middleware is third-party software that stitches together your set of chosen technologies for a set series of tasks. Like any tool, it’s designed for certain types of jobs. You pick it based on what you are trying to accomplish, within the scope of connecting isolated software in your project. This makes it different from a Framework or an API. It’s all specialized code but they all have different purposes. Understanding the nuances here will help you in your career in the long run, so keep this in mind.

If you’d like further clarification on middleware check this out quote. I also provided links below which will further explain this concept in greater detail.

This is not Middleware 🐢
“Middleware is software that bridges gaps between other applications, tools, and databases in order to provide unified services to users. It is commonly characterized as the glue that connects different software platforms and devices together.”- talend

How’s it work? 🤨

😯 Umm… never knew you could that 😳

If you have ever set up a “vanilla/bare-bones” Node.js server you’ve noticed that requests and responses are handled with HTTP.createServer(). You may have even built a more advanced build using routing, body parsing, and using res.write() for this setup. Express.js however, handles this setup a bit differently.

You remember, right ? 🤓…import and declare stuff here…const server = http.createServer((res,req) => {“do stuff here with res or req”})… listen for port here…

The framework makes room for middleware functions at this level. This is a different design pattern than what you’re using. I’ll focus on this setup, which is a fundamental building block to Express.js. This may take a bit longer to set up but when you get the hang of it, you’ll cut down on time debugging😊 !

Will be going from something like this…

Vanilla Node.js 🤔…in ./app.jsconst http = require(‘http’);const routes = require(‘./routes’)const server = http.createServer(routes.handler);server.listen(3000); — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -To something like this…Node.js + Express.js 🤩…in ./app.jsconst http = require(‘http’);const express = require(‘express’); ←- changed 😮const app = express(); ←- changed 😮const server = http.createServer(app); ←- changed 😮server.listen(3000);*** It get’s more complex then this… ***

Looks different right? 👀

Express.js has a Middleware Pattern, which “funnels” or moves from one Middleware Function (or just “Middleware”) to the next. Think of this pattern as a series of filters or gates. You may have even written a pattern like this yourself with a series of functions and conditional logic.

Middleware functions manage the incoming HTTP Request and based on some logic and functions it will return an HTTP Response. This standardization of setup allows us to focus on other important things in development. The Middleware pattern is widely used and accepted by Node Developers so let’s spend some time exploring it, as it gives us some great advantages.

Example with Security Feature from the server-side

About Middleware(3rd party) + Middleware PatternThe Middleware Pattern allows us to ALSO use third party middleware. Which we dicussed earlier. Try not to confuse this with the concept of middleware functions/middleware! 😝

Understanding .use() + .next()

Hurray Tutorials!!!! 🐢 😀 😎

Let’s apply our Middleware Pattern to a simple Node.js server. Will be using two handy methods that come with Express.js. Hopefully, through this simple exercise, you’ll get a better understanding of how the setup works.

Let’s start with some of the code we looked at earlier on…

…still in ./app.jsconst http = require(‘http’);const express = require(‘express’);const app = express(); ← imported + invoked 🤨const server = http.createServer(app); ← We need to refactor 💡server.listen(3000);

We have already imported Express.js and invoked it, which is saved under the app variable. Will have to refactor the server variable though, as it doesn’t fit our Pattern.

const http = require(‘http’);const express = require(‘express’);const app = express();app.use(() => { }); ← .use() method takes a function 🤔const server = http.createServer(app);server.listen(3000);

Let’s start with .use() method. Which is a very handy function, which excepts an array of request handlers. The method has other use cases, but this blog will just discuss the relevant features.

.use() always takes a function, which will be executed ON EVERY INCOMING REQUEST. It always has 3 arguments: a request object, a response object, and .next() function which is our 2nd method will explore.

const http = require(‘http’);const express = require(‘express’);const app = express();app.use((req,res,next) => {}); ← takes 3 arguements 🧐const server = http.createServer(app);server.listen(3000);

Let’s console.log() inside this function and run our server. If we enter our URL in the browser, our console.log should fire up. The browser will keep loading, not to worry, just head to your terminal. Giving us the console.log() message.

Don’t shy away from app.use()😂
app.use((req,res,next) => {console.log(‘First Middleware Function!!!’) ←- 😮});

Given our newfound knowledge of Express.js’s Middleware Pattern, how do we move to the next middleware? Simple, we use the .next() method I mentioned, otherwise we hard stop at the first Middleware. This takes us to the following middleware. Let’s write another middleware like before and deploy the .next() method like so…

const http = require(‘http’);const express = require(‘express’);const app = express();app.use((req,res,next) => {console.log(‘First Middleware Function!!!’)next(); ←- use next() 👍});app.use((req,res,next) => {console.log(‘Next Middleware Function!!!’)});const server = http.createServer(app);server.listen(3000);

Let’s repeat our test. We should see 2 different messages in our terminal ‘First Middleware Function!!!’ and after that, we should see ‘Next Middleware Function!!!’. Notice the order, and look at how we wrote our functions.

const http = require(‘http’);const express = require(‘express’);const app = express();… MIDDLE WARE 1st, I run first … ️🐇… MIDDLEWARE 2nd, I run second … 🐢const server = http.createServer(app);server.listen(3000);

This is how we handle user logins, auth, security features, etc. It starts with the Middleware. I encourage you to play around with this concept further as it’s a great sandbox for learning. Try running middleware without a .next()method. See what fires off first, second, and so forth.

const http = require(‘http’);const express = require(‘express’);const app = express();app.use((req,res,next) => {console.log(‘First Middleware Function!!!’)next();});app.use((req,res,next) => {console.log(‘Next Middleware Function!!!’)});const server = http.createServer(app);server.listen(3000);

Conclusion

Mario + his Middlewares

Hopefully, you’ve learned a bit more about the Express.js Middleware Pattern and its importance. Please take the time to fully understand this fundamental concept as much of Express.js is built off of it. We are clearly just scratching the surface with Express.js, so please stay tuned 📺 . I’ll be posting additional tutorials and breakdowns about this amazing Web framework every week.

Happy Coding + Ciao !!! 😽 👋 🎮

Cool Links Below 👎

Middleware Functions: https://expressjs.com/en/guide/using-middleware.htmlOn middleware(talend): https://www.talend.com/resources/what-is-middleware/#:~:text=Middleware%20is%20software%20that%20bridges,software%20platforms%20and%20devices%20together.

--

--

Sam Lesser

Career Changer, Software Engineer & Web Developer