Eric The Coder
Eric The Coder Blog

Eric The Coder Blog

NodeJS + Express part 3: Middleware

NodeJS + Express part 3: Middleware

Eric The Coder's photo
Eric The Coder

Published on Oct 28, 2021

3 min read

Here is a series of articles that will allow you to create backend applications with NodeJS + Express.

This series is the continuation of my series on the basics of NodeJS. If you don't have basic knowledge of NodeJS read this the first article of the series.

Node.js is today a must, so it is essential for a developer to master it.

So I will publish a new article about every two days and little by little you will learn everything there is to know about Node.js + Espress

To not miss anything follow me on twitter: twitter.com/EricTheCoder_


Middleware

Middleware are functions that execute during the request to the server. Those functions have access to the request and response parameters so can perform many things to enhance/automate API functionalities

The middleware sit in between the request and response

user request -> midlleware -> response

Create your first Middleware

Let's assume we want a function to log the url address of the request every time a page is visit.

Without middleware we could have done this with code like that:

app.get('/about', (req, res) => {
    console.log(req.url)
    console.log(req.params)
    console.log(req.query)
    return res.send('About Page')
})

That will work just fine but what if we have 100 different routes? We cannot copy/paste those console.log() lines to every routes.

One solution is to put those logs in middleware function

const logger  = (req, res, next) => {
    console.log(req.url)
    console.log(req.params)
    console.log(req.query)
    next()
}

That's a pretty simple function. You are already familiar with the req and res parameters. The new thing here is the next() function. The next() function is a Espress pre-define function that give back the control to the calling routes. After executing the console.log() the request need to continue is road to the calling route.

Here is a full exemple of a middleware

const logger  = (req, res, next) => {
    console.log(req.url)
    console.log(req.params)
    console.log(req.query)
    next()
}

app.use(logger) // execute your middleware for all requests

app.get('/about', (req, res) => {
    return res.send('About Page')
})

When the user visit /about Express will execute the app.get(). But just before, it will execute the middleware specified in the app.use(). Once the middleware is executed the next() will continue the app.get() execution

Here is the sequence of execution:

client request → /about ⇒ logger() → app.get() → client response

When creating a middleware you are not force to use the next(). You can send your own response and override/omit the app.get() completely

const logger  = (req, res, next) => {
    console.log(req.url)
    console.log(req.params)
    console.log(req.query)
    res.send('Custom About page')
}

Here is the sequence of execution:

client request → /about ⇒ logger() → client response

If the middleware only apply to one or two route you can use this syntaxe to execute the middleware only for those routes

const logger  = (req, res, next) => {
    console.log(req.url)
    console.log(req.params)
    console.log(req.query)
    next()
}

app.get('/about', logger, (req, res) => {
    return res.send('About Page')
})

Noted we did not use the app.use() but only specified a middleware function as a parameter of the app.get()

You can also execute your middleware only for request that are under a specific path ex: /api

app.use('/api', logger)

Multiple middleware can be use

app.use([logger, auth])

Noted the middleware will be executed in the same order as declare.

Middleware can change the request object

const auth  = (req, res, next) => {
    const user = req.query.user
    if (user === 'admin') {
        req.user = ( name: 'admin', id: 1 }
        next()
    } else {
        res.status(401).send('Unauthorized')
    }
}

In the last exemple we add a user object to the request. That user object can now be use in the routes.

app.use(auth)

app.get('/about', (req, res) => {
    console.log(req.user)
    return res.send('About Page')
})

This exemple as been ultra simplified but it show the real power of middleware

Conclusion

That's all for today, follow me on twitter: twitter.com/EricTheCoder_ to be notified of the publication of the next article (within two days).

Did you find this article valuable?

Support Eric The Coder by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
 
Share this