0% found this document useful (0 votes)
5 views7 pages

MVC Routing and Middleware in ExpressJS

Uploaded by

Smoked By Cylien
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views7 pages

MVC Routing and Middleware in ExpressJS

Uploaded by

Smoked By Cylien
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Router, Middleware, MVC

Table of Content –
1. Router.
2. MVC Architecture.
3. Middleware.

1. Router –
Using expressJS we can create routes. Routes helps us to segregate our each routes. For
example there can be one route called as authentication inside which we will specify our
auth routes for login, logout, signin and signout. We are segregating all of the routes so
that we will not flood the [Link] file. So in order to segregate routes, we can first
create a folder called routes and then for example create a post route –

//[Link]
const router = require('express').Router();

[Link]("/user", (req, res) => {


[Link](200).json({
id: '123423',
title: 'demo title',
imgUrl: "[Link]
});
});

[Link] = router;

After exporting the router, we will go back to [Link] file and then do `[Link]()` after
the `[Link]()` route. `[Link]()` is a middleware. Inside `[Link]()` function we will
define our route and then the path of our route:
//[Link]
const postRouter = require('./routes/[Link]');
//..and all the default codes..

[Link]("/", (req, res) => {


[Link](200).json({
status: "Ok"
});
});

[Link]('/post', postRouter);
//.. any other routes more than one..

For now there can be only one or two routers, but in future we will have a lot of routers,
and then our [Link] file will start flooding, so, we can go even higher while segregating
our routes.
So inside routes folder we will create a folder called as `v1` and then create an `[Link]`
file inside it, and inside the routes folder create another file `[Link]`. now let us start
connecting these files with each other –

// [Link] file of v1 folder


const router = require('express').Router();
const postRouter = require('./[Link]');

[Link]('/post', postRouter);

[Link] = router;
We have connected our [Link] file with our [Link] file which is inside v1 folder.

//[Link] file of routes folder


const router = require('express').Router();
const v1 = require('./v1/index');

[Link]('/v1', v1);

[Link] = router;
We have connected v1’s folder [Link] file into our routes folder [Link] file.
//Our root [Link] file
const express = require('express');

//Our routes [Link] file.


const mainRoute = require('./src/routes/index')

const app = express();

//allowing json files inside our code –


[Link]([Link]());

//Using the chained routes which we just created.

[Link]('/', mainRoute)

[Link]('/', (req, res) => {


[Link](200).json({
message: "OK"
});
});

[Link](3000, () => {
[Link]('server started');
});
And finally we have connected routes [Link] file with our root [Link] file

2. MVC Architecture –
MVC (Model, View, Controller) is simply a design or architectural pattern used in
software engineering. While this is not a hard rule, but this pattern helps developers
focus on a particular aspects of their application, one step at a time. The main goal of
MVC is to split large applications into specific sections that have their own individual
purpost.
 Model – As the name implies, a model is a design or structure. In the case of
MVC, the model determines how a database is structured, defining a section of
the application that interacts with the database.
 View – View or Routes, is the page or output that we see after hitting the API.
 Controller – The controller interacts with the model and serves the response and
functionality to the view. When an end user makes a request, it’s sent to the
controller which interacts with the database.
How these three talk to each other

First we will create 2 folders on the parent directory, one will be controllers, second will be
models. Inside models folder we will, as an example, create [Link] file. Inside the [Link] file we
will create a dummy data for demonstration. In future we will get these data from our
MongoDB database –

//[Link]
const users = [
{
name: "abc",
email: "abc@[Link]",
password: 1234
},
{
name: "def",
email: "def@[Link]",
password: 4321
},
];

[Link] = users;

Now inside the controllers folder we will create an [Link] file and create a login
controller inside it –

const User = require('../models/User')


const loginController = async(req, res) => {
const email = [Link];
const password = [Link];

[Link](email, password);

if (!email && !password) {


return [Link]('Email and Password are required.')
};

if (!email) {
return [Link]('email is required.')
};

if (!password) {
return [Link]('password is required.')
};

const user = [Link](item => [Link] === email);

if (!user) {
return [Link]('User not found');
};

if ([Link] !== password) {


return [Link]('password is incorrect');
};

const name = [Link];


[Link]({
name
});
};

[Link] = {
loginController
};
Logic of creating login controller (as a demo only).

Now inside [Link] file we will use our controller –

const { loginController } = require('../../controllers/[Link]');


const router = require('express').Router();
[Link]('/login', loginController);

[Link] = router;

This is how the models, routes and controllers talk with each other and perform such elegance
work.

3. Middleware –
ExpressJS is a routing and middleware web framework that has minimal functionality of
its own. Middleware functions are functions that have access to the request object
(req), the response object (res), and the next middleware function (next) in the apps
request-response cycle. The next middleware function is commonly denoted by a
variable named next.

Middleware functions can perform the following tasks:


 Execute any code.
 Make changes to the request and the response object.
 End the request-response cycle.
 Call the next middleware function in the stack.
If the current middleware function does not end the request-response cycle, it must call
next() to pass control to the next middleware fuinciton. Otherwise, the request will be
left hanging.
The next example shows a middleware function with no mount path. The function is
executed every time the app receives a request.
We will create a middleware function like this –

// [Link] file for middleware


const m1 = (req, res, next) => {
[Link]("api was called");
next();
}

[Link] = m1;
Now we will use this middleware like this –
//Inside our root [Link] file
const m1 = require('./src/middlewares/m1');
//..the rest of the code of root [Link] file..

[Link]('/', m1, mainRoute);


We just passed the middleware function in between of the api path and the api routes.
This is how we create and use a middleware. Whenever any of the api will get hit, it will
console log saying `api was called`.

Common questions

Powered by AI

The separation of controllers and models in an MVC-designed web application greatly contributes to scalability by dividing concerns effectively. Models handle data structure and database interactions independently of the business logic managed by controllers. This separation allows developers to scale the database-related components independently of the application logic, and vice versa. It also enables different developers or teams to work on distinct components concurrently without conflict, facilitating agile development practices and easier testing and debugging processes .

Implementing versioning in route management can lead to challenges like increased complexity in handling backward compatibility, potential increase in code redundancy, and difficulty in maintaining multiple versions over time. These challenges can be addressed by clearly delineating the obligations of each version, consistently refactoring shared functionality into middleware or utilities to reduce redundancy, and maintaining comprehensive documentation. Testing across versions helps ensure smooth transitions and proper support for deprecated versions .

The use of a 'next' function in middleware allows for the chaining of middleware functions, ensuring that each function in the sequence has an opportunity to execute. It is particularly beneficial because it enables control to be passed to subsequent middleware or route handlers when the current function's processing is complete. This essential feature keeps the application's request-response cycle from hanging and supports modular and clear code organization .

Separating route logic into different files in ExpressJS is significant because it enhances code organization, readability, and maintainability. It prevents the main index.js file from becoming overwhelmed with numerous route definitions, thus focusing on just importing and utilizing these routes. This separation aligns with modular programming principles, making it easier to manage and scale the application .

To avoid cluttering the index.js file, ExpressJS routes can be organized by creating separate route files and using a folder structure. For example, create a routes folder, then define individual route files such as post.route.js, export them, and integrate them into the main file using `app.use()`. Additionally, further organization can be achieved by creating a versioned folder (e.g., v1) within the routes folder and connecting these organized route files to the root index.js file .

Middleware can enhance an API's functionality by implementing logging, authentication, or input validation. For instance, adding a middleware that logs request details such as the method and path could provide insights into API usage patterns. Authentication middleware could enforce security by checking user credentials before allowing access to certain routes. Middleware for input validation can ensure the integrity and correctness of incoming data before it reaches the business logic, thus preventing errors or security vulnerabilities .

Middleware functions in ExpressJS serve as intermediate handlers that have access to the request object, response object, and the next function in the request-response lifecycle. They can execute any code, modify request and response objects, terminate a request-response cycle, and call the next middleware. If the request-response cycle is not terminated, the middleware must call `next()` to pass control to the next function. Middleware can be executed on all requests or conditionally based on specific paths .

In MVC architecture, the Model defines the application's data structure and manages interactions with the database. The View is the interface presented to the user (e.g., web pages viewed after an API call). The Controller processes incoming requests, interacts with the Model for data, and delivers the response to the View .

The `express.json()` middleware in an ExpressJS application parses incoming requests with JSON payloads, allowing the application to automatically decode these payloads and attach them to the `req.body` property. This is crucial for applications that receive and handle JSON-formatted data from clients, as it simplifies the process of accessing and manipulating request data without requiring explicit parsing logic in individual route handlers .

In an MVC architecture, the Controller acts as an intermediary between the Model and the View. It receives user requests and processes them, often by retrieving relevant data from the Model. After processing this data, the Controller sends a response to the View, which ultimately renders the output. By decoupling the data access and presentation logic, Controllers enhance modularity and facilitate easier updates and maintenance of application components .

You might also like