Learning MVC

By Robin Herzig

View source code at:

https://github.com/100devs/todo-mvc

What is MVC?

"MVC (Model-View-Controller) is a pattern in software design commonly used to implement user interfaces, data, and controlling logic. It emphasizes a separation between the software's business logic and display. This "separation of concerns" provides for a better division of labor and improved maintenance. Some other design patterns are based on MVC, such as MVVM (Model-View-Viewmodel), MVP (Model-View-Presenter), and MVW (Model-View-Whatever)."

- MDN Web Docs Glossary

What is MVC?

"MVC (Model-View-Controller) is a pattern in software design commonly used to implement user interfaces, data, and controlling logic. It emphasizes a separation between the software's business logic and display. This "separation of concerns" provides for a better division of labor and improved maintenance. Some other design patterns are based on MVC, such as MVVM (Model-View-Viewmodel), MVP (Model-View-Presenter), and MVW (Model-View-Whatever)."

- MDN Web Docs Glossary

But what does that mean?

What is MVC?

MVC is an architectural paradigm that creates a structure where applications can be created modularly.

What is MVC?

MVC is an architectural paradigm that creates a structure where applications can be created modularly.

This separation of backend processes helps the application scale in complexity because it's easier to code, debug, and test each part as an individual.

What is MVC?

MVC is an architectural paradigm that creates a structure where applications can be created modularly.

 It's composed of three main parts:

  1. Model: Accesses the database.
  2. View: Renders HTML  for the client.
  3. Controller: Processes CRUD requests and server-side logic.

This separation of backend processes helps the application scale in complexity because it's easier to code, debug, and test each part as an individual.

What are the parts of MVC?

The model defines data structure and sends or receives this data from the database.

Model

View

Controller

The view handles data presentation, typically populated using information retrieved from the model and then rendered using a template engine.

Model

View

Controller

What are the parts of MVC?

The controller receives every request and, using information provided within it, is coded to direct that information to the correct receiver.

Model

View

Controller

What are the parts of MVC?

How do these components interact?

Client

Controller

Model

View

Above is a model of this architecture.

Database

Above is a model of this architecture.

How do these components interact?

Client

Controller

Model

View

Database

Above is a model of this architecture.

1. The Client makes a GET request.

How do these components interact?

Client

Controller

Model

View

Database

Above is a model of this architecture.

1. The Client makes a GET request.

2. The Controller requests data from the Model.

How do these components interact?

Client

Controller

Model

View

Database

Above is a model of this architecture.

1. The Client makes a GET request.

2. The Controller requests data from the Model.

3. The Model requests data from the Database.

How do these components interact?

Client

Controller

Model

View

Database

Above is a model of this architecture.

1. The Client makes a GET request.

2. The Controller requests data from the Model.

3. The Model requests data from the Database.

4. The Database responds with the data.

How do these components interact?

Client

Controller

Model

View

Database

Above is a model of this architecture.

1. The Client makes a GET request.

2. The Controller requests data from the Model.

3. The Model requests data from the Database.

4. The Database responds with the data.

5. The Model responds to the Controller.

How do these components interact?

Client

Controller

Model

View

Database

Above is a model of this architecture.

1. The Client makes a GET request.

2. The Controller requests data from the Model.

3. The Model requests data from the Database.

4. The Database responds with the data.

5. The Model responds to the Controller.

6. The Controller requests a render from the View.

How do these components interact?

Client

Controller

Model

View

Database

Above is a model of this architecture.

1. The Client makes a GET request.

2. The Controller requests data from the Model.

3. The Model requests data from the Database.

4. The Database responds with the data.

5. The Model responds to the Controller.

6. The Controller requests a render from the View.

7. The View responds with a render.

How do these components interact?

Client

Controller

Model

View

Above is a model of this architecture.

Database

1. The Client makes a GET request.

2. The Controller requests data from the Model.

3. The Model requests data from the Database.

4. The Database responds with the data.

5. The Model responds to the Controller.

6. The Controller requests a render from the View.

7. The View responds with a render.

8. The Controller responds to Client with a rendered webpage.

How do these components interact?

Client

Controller

Model

View

Database

What patterns do we see?

How do these components interact?

Client

Controller

Model

View

Database

What patterns do we see?

- The Client only connects to the Controller.

How do these components interact?

Client

Controller

Model

View

Database

What patterns do we see?

- The Client only connects to the Controller.

- The Controller connects between the Model and View.

How do these components interact?

Client

Controller

Model

View

Database

What patterns do we see?

- The Client only connects to the Controller.

- The Controller connects between the Model and View.

- The Model connects to the Database.

How do these components interact?

Client

Controller

Model

View

Database

What patterns do we see?

- The Client only connects to the Controller.

- The Controller connects between the Model and View.

- The Model connects to the Database.

Again, this separation of backend processes helps the application scale in complexity because it's easier to code, debug, and test each part as an individual.

How to further optimize?

We can amplify the advantages of MVC by adding another component: the Routes.

Routes

Mongoose

Schemas

How to further optimize?

We can amplify the advantages of MVC by adding another component: the Routes.

router.get('/', async (req,res)=>{
  try{  const todoItems = await Todo.find()
    const itemsLeft = await Todo.countDocuments({completed: false})
    res.render('todos.ejs', {todos: todoItems, left: itemsLeft})
  }catch(err){
   console.log(err)
  }
})

To create the route file, separate the route from the controller:

Routes

Mongoose

Schemas

How to further optimize?

We can amplify the advantages of MVC by adding another component: the Routes.

router.get('/', async (req,res)=>{
  try{  const todoItems = await Todo.find()
    const itemsLeft = await Todo.countDocuments({completed: false})
    res.render('todos.ejs', {todos: todoItems, left: itemsLeft})
  }catch(err){
   console.log(err)
  }
})

To create the route file, separate the route from the controller:

Routes

Mongoose

Schemas

How to further optimize?

Routes

Mongoose

Schemas

Installing the Mongoose module through NPM makes writing MongoDB logic much easier.

How to further optimize?

Routes

Mongoose

Schemas

"Mongoose provides a straight-forward, schema-based solution to model your application data. It includes built-in type casting, validation, query building, business logic hooks and more, out of the box."

- Mongoose JS official website

Installing the Mongoose module through NPM makes writing MongoDB logic much easier.

How to further optimize?

The Mongoose module includes features to create schemas, which are object templates for MongoDB documents.

Routes

Mongoose

Schemas

How to further optimize?

The Mongoose module includes features to create schemas, which are object templates for MongoDB documents.

Routes

Mongoose

Schemas

These templates can be used to limit data types:

How to further optimize?

The Mongoose module includes features to create schemas, which are object templates for MongoDB documents.

Routes

Mongoose

Schemas

These templates can be used to limit data types:

const blogSchema = new Schema({
  title:  String, // String is shorthand for {type: String}
  author: String,
  body:   String,
  comments: [{ body: String, date: Date }],
  date: { type: Date, default: Date.now },
  hidden: Boolean,
  meta: {
    votes: Number,
    favs:  Number
  }
});

How do these components interact?

Routes

Controller

Model

View

Database

Client

Lets see a practical GET example.

How do these components interact?

const todoRoutes = require('./routes/todos')
app.use('/todos', todoRoutes) // Go to routes/todos.js to find the route

server.js

Routes

Controller

Model

View

Database

Client

How do these components interact?

const todosController = require('../controllers/todos')
router.get('/', todosController.getTodos) // Go to controllers/todos.js to complete the route

routes/todos.js

Routes

Controller

Model

View

Database

Client

How do these components interact?

const Todo = require('../models/Todo')
getTodos: async (req,res)=>{
  try{
    const todoItems = await Todo.find() // Go to models/Todo.js to request data from the database
    const itemsLeft = await Todo.countDocuments({completed: false})
    res.render('todos.ejs', {todos: todoItems, left: itemsLeft})
  }catch(err){
    console.log(err)
  }
}

controllers/todos.js

Routes

Controller

Model

View

Database

Client

How do these components interact?

const TodoSchema = new mongoose.Schema({ // Use the mongoose module to return the documents
  todo: {
    type: String,
    required: true,
  },
  completed: {
    type: Boolean,
    required: true,
  }
})
module.exports = mongoose.model('Todo', TodoSchema)

models/Todos.js

Routes

Controller

Model

View

Database

Client

How do these components interact?

const TodoSchema = new mongoose.Schema({ 
  todo: {
    type: String,
    required: true,
  },
  completed: {
    type: Boolean,
    required: true,
  }
}) // After retrieving information from the database, respond to the controller
module.exports = mongoose.model('Todo', TodoSchema)

models/Todos.js

Routes

Controller

Model

View

Database

Client

How do these components interact?

Routes

Controller

Model

View

Database

Client

const Todo = require('../models/Todo')
getTodos: async (req,res)=>{
  try{
    const todoItems = await Todo.find()
    const itemsLeft = await Todo.countDocuments({completed: false})
    res.render('todos.ejs', {todos: todoItems, left: itemsLeft}) // Render todos.ejs
  }catch(err){
    console.log(err)
  }
}

controllers/todos.js

How do these components interact?

Routes

Controller

Model

View

Database

Client

const Todo = require('../models/Todo')
getTodos: async (req,res)=>{
  try{
    const todoItems = await Todo.find()
    const itemsLeft = await Todo.countDocuments({completed: false})
    res.render('todos.ejs', {todos: todoItems, left: itemsLeft})
  }catch(err){
    console.log(err)
  }
} // Respond to the client with the rendered HTML

controllers/todos.js

How do these components interact?

Routes

Controller

Model

View

Database

Client

The client's GET request is fulfilled!

How are these files organized?

The last thing we'll look at is how websites with multiple pages can organize their file structure.

How are these files organized?

Database

Client

example.org/

example.org/about

How are these files organized?

Routes

Controller

Model

View

Database

Client

Routes

Controller

Model

View

example.org/

example.org/about

How are these files organized?

Routes

Controller

Model

View

Database

Client

Routes

Controller

Model

View

example.org/

example.org/about

How are these files organized?

Routes

Controller

Model

View

Database

Client

Routes

Controller

Model

View

example.org/

example.org/about

How are these files organized?

Routes

Controller

Model

View

Database

Client

example.org/

As you can see, each page has its own set of Routes, Controllers, Models, and Views.

How are these files organized?

As you can see, each page has its own set of Routes, Controllers, Models, and Views.

The website as a whole shares the same server.js file and database.

Routes

Controller

Model

View

Database

Client

example.org/

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

On the left is a condensed version of the flow chart from the previous page.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

On the left is a condensed version of the flow chart from the previous page.

We'll use it to demonstrate how the files are organized on the server.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

3. The Routes sends the request to the correct controller.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

3. The Routes sends the request to the correct controller.

4. The Controller requests data from the Model.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

3. The Routes sends the request to the correct controller.

4. The Controller requests data from the Model.

5. The Model requests data from the Database.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

3. The Routes sends the request to the correct controller.

4. The Controller requests data from the Model.

5. The Model requests data from the Database.

6. The Database responds with the data.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

3. The Routes sends the request to the correct controller.

4. The Controller requests data from the Model.

5. The Model requests data from the Database.

6. The Database responds with the data.

7. The Model responds to the Controller.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

3. The Routes sends the request to the correct controller.

4. The Controller requests data from the Model.

5. The Model requests data from the Database.

6. The Database responds with the data.

7. The Model responds to the Controller.

8. The Controller requests a render from the View.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

3. The Routes sends the request to the correct controller.

4. The Controller requests data from the Model.

5. The Model requests data from the Database.

6. The Database responds with the data.

7. The Model responds to the Controller.

8. The Controller requests a render from the View.

9. The View responds with a render.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

3. The Routes sends the request to the correct controller.

4. The Controller requests data from the Model.

5. The Model requests data from the Database.

6. The Database responds with the data.

7. The Model responds to the Controller.

8. The Controller requests a render from the View.

9. The View responds with a render.

10. The Controller responds to Client with a rendered webpage.

How are these files organized?

Routes

Controller

Model

View

Database

example.org/

Client

config

    database.js

controllers

    homepage.js

    about.js

models

    homepage.js

    about.js

public

    ...

routes

    homepage.js

    about.js

views

    homepage.js

    todos.ejs

server.js

1. The Client makes a GET request.

2. The server.js receives the request, forwards it to the applicable route.

3. The Routes sends the request to the correct controller.

4. The Controller requests data from the Model.

5. The Model requests data from the Database.

6. The Database responds with the data.

7. The Model responds to the Controller.

8. The Controller requests a render from the View.

9. The View responds with a render.

10. The Controller responds to Client with a rendered webpage.

Any questions?

Learning MVC

By Robin Herzig

View source code at:

https://github.com/100devs/todo-mvc

Learning MVC

By Robin Herzig