Creating your own ExpressJS from scratch (Part 2) - Middlewares and Controllers

wesleymreng7

Wesley Miranda

Posted on April 9, 2023

Creating your own ExpressJS from scratch (Part 2) - Middlewares and Controllers

Today I want to show you more about how to create a Web Framework like Express.js. This is part 2 of a series of a tutorial that I am creating. You missed part 1, check it out here

We are going to apply middleware and controllers for our routes, for it We need to use the middleware pattern. If you want to know more about it, I will let a link at the end of this tutorial.

Let's get started.


Middlewares

src/app.js

// (1)
const dispatchChain = (request, response, middlewares) => {
    return invokeMiddlewares(request, response, middlewares)
}

// (2)
const invokeMiddlewares = async (request, response, middlewares) => {

    if (!middlewares.length) return;

    const currentMiddleware = middlewares[0];

    return currentMiddleware(request, response, async () => {
            await invokeMiddlewares(request, response, middlewares.slice(1));
    })
}
// (3) 
const serverHandler = async (request, response) => {
    const sanitizedUrl = sanitizeUrl(request.url, request.method)

    const match = matchUrl(sanitizedUrl)

    if (match) {
            const middlewaresAndControllers = routes.get(match)
            await dispatchChain(request, response, [...middlewaresAndControllers])
    } else {
            response.statusCode = 404
            response.end('Not found')
    }
}
Enter fullscreen mode Exit fullscreen mode

From the code sections above:

  1. The dispatchChain as the name suggests, Will dispatch a chain of functions.

  2. This is a middleware handler, responsible to execute and remove the function from the array of middleware, till there is no more function to execute.

  3. Now we can modify our serverHandler function, to execute the middlewares for the current route.


Testing

index.js

const App = require('./src/app')

const app = App()


app.get('/test/test2', function test() { }, function test2() { })
app.post('/test', (req, res) => console.log('test'))
app.patch('/test', (req, res) => console.log('test'))
app.put('/test', (req, res) => console.log('test'))
app.del('/test', (req, res) => console.log('test'))

// (1)
const mid1 = (req, res, next) => {
    console.log('mid1')
    next()
}
// (2)
const mid2 = (req, res, next) => {
    console.log('mid2')
    next()
}
// (3)
const controller = (req, res) => {
    console.log('controller')
    res.end('controller')
}
// (4)
app.get('/middleware', mid1, mid2, controller)



const start = async () => {
    app.run(3000)
}

start()
Enter fullscreen mode Exit fullscreen mode

From the code sections above:

  1. First middleware function using the next function to pass to the next middleware.

  2. Second middleware function using the next function to pass to the next middleware.

  3. Controller to route without next function. Here we can return something to the client, as a message for example.

  4. Applying the middleware and controller to a route.

Middleware pattern is not so difficult to apply, in a few code lines you can use it in your application.

At this link you can see more about the middleware pattern.

Also, you can take a look at the code here

Don't hesitate to follow me to receive more content.

Thanks!

💖 💪 🙅 🚩
wesleymreng7
Wesley Miranda

Posted on April 9, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related