MVC
The Model-View-Controller is a design pattern which is used to divided related program logic into three interconnected elements. Trygve Reenskaug (amazing name!) came up with in 1979, and his concept is still in use today. You can check out his website and see his original paper here. His design pattern defines the roles each element, as well as how they interact with each other (which element talks to which other element(s)).
How does it divide up everything? With boundaries. What are the boundaries? Just imaginary lines basically. In practice it is different logic into different files based on it’s role. Dividing things up has many advantages. It’s almost always easier to read and understand what is going on, and the code separated out is now often easily reusable if needed elsewhere. During development, each part can be developed by separate teams/individuals, without a bottleneck.
Each of the three parts to this design pattern (model, view, controller) can hold many different files inside them, not just one. Each of these three parts is often referred to as a layer, for example the “View layer”.
In the past the MVC design pattern was mostly used for GUIs (Graphical User Interfaces) on computer desktops. Now, it is often used for web based applications.
Photos
Well, that does not explain exactly how it is used. So here are a bunch of photos I searched for. I tried to find ones using Nodejs.
Model
The model component is used for data-related logic that the user interacts with, stores data. File structure is typically have a folder labeled “models” and placing different models inside it. Here we use Nodejs for our model, which uses a mongoose schema to get data.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Food = new Schema ({
name: { type: String, required: true },
calories: { type: String, required: true },
});
module.exports = mongoose.model('Food', Food)
View
The view displays things to the user, using the model to format it. For web base applications, the views folder will contain things like CSS/SASS and HTML files. With Nodejs, often a template engine such as ejs will be used as well.
Controller
Controls the requests from the view, and displays them back to the view. Here we create a controllers directory, and place all controller files inside it. In this case the controller would be responsible for handling requests and responses the user sends to it through the view.
const path = require('path');
const Food = require('../models/foods');
exports.index = function (req, res) {
res.sendFile(path.resolve('views/food.html'));
};
exports.create = function (req, res) {
var newFood = new Food(req.body);
console.log(req.body);
newShark.save(function (err) {
if(err) {
res.status(400).send('Oops');
} else {
res.redirect('/foods/food');
}
});
};
exports.list = function (req, res) {
Food.find({}).exec(function (err, food) {
if (err) {
return res.send(500, err);
}
res.render('food', {
foods: foods
});
});
};
Basically, the user will see the view, and when they manipulate it (such as by clicking a button that requests some new data) they are interacting with the controller. The controller talks to the model about the request, and the model sends what it wants displayed back to the controller, which updates the view.
Another way of saying the same thing: The controller receives inputs from the user through the view, and sends them to the model. The model takes the request, does something with it, and sends it back to the controller. The controller updates the view with this response, and the user now sees it.
Real life Node
This is often used with Node, and just means that you separate out all your authorization and route handlers into a separate directory. Instead of having them in the main app.js or index.js location. It is a big help organizing the code, making it easier to read and work on during development and in the future. Here is a sample file structure from a project:
Routing
Remember how MVC was originally used for things like desktop applications? Well, there was no network involved with that. With our Nodejs web based app, there is. The user will be a client, and the view a browser. The controller is located on your server, far away across the internet. To interact with the server, we send HTTP requests to it from the user/client/view.
Routing just matches the requests the server gets with what function to use. A POST request made use a function to send the data to a MongoDB database, a GET request might send you back a photo of a kitten. To make this easier, we use express to help with the routing. With a separate routes folder containing each route, you can export the logic of each route to a controller. In the example below we have a “/routes/auth” file:
////Express auth routes, what functions each route should perform.
//// Destructuring the Router object from the express NPM package
const { Router } = require("express");
///// Get the controller object,
//which exports a bunch of different functions
const authController = require("../controllers/authController");
///Init new router object,
//can save as any name you want,
//but router is most common.
const router = Router();
///When a route is hit,
//uses the the authController object
//to access a function for that
//route and do something cool
//Note the trailing slash
router.get("/signup/", authController.signup_get);
router.post("/signup/", authController.signup_post);
router.get("/login/", authController.login_get);
router.post("/login/", authController.login_post);
module.exports = router;