So you're learning full-stack JavaScript and starting to get into the backend of things. Working with Node, Express, and MongoDb and the server.js file is a mile long and full of spaghetti.
Enter MVC | Model View Controller
MVC is both the workflow of how your full-stack program handles requests and how you organize your files based on that flow. I know starting with a flowchart image probably doesn't make sense, but we will need this for reference. There is also a TL;DR down at the bottom if deep-diving isn't your thing.
Let's Break it Down
In my opinion, this should be 'Routes, Controller, Model, View' instead of 'Model View Controller' and as I go over the process below you might see why too.
Starting with the user, the happy green smiley, who wants to visit a website with a to-do list. When this user goes to the website they'll be sending a route request which has a bunch of different information like where they want to go and what they want to do. For our purpose today, the user is going to be requesting on the /todos
route.
Here's a peek at the code so we can see what will happen.
server.js
Aaah, where do we begin?! Realistically we only need to look at this piece of code for now.
So when a user sends requests on the '/todos'
route, our program will see that and fire them off to the todoRoutes
.
Routes
Now why would you want to have a separate route file, even if it's not a part of traditional MVC? Well, it adds a level of abstraction between the different steps in the workflow, breaking it down into smaller bite-sized pieces. Without routes having their own separate place they would be bundled in with the Controller and you'll see why combining these can make things confusing.
Now, back to the todosRoutes
...
You can see the todosRoutes
has instructions on how to handle different requests. Depending on what route and request type it'll hand you off to a different controller.
This is a get
request on the /todos
/
root route, which will send us over to the todosController
and look at getTodos
for what to do next.
Controller
This is where the ✨ MVC magic ✨ starts to happen and the different aspects of the Model View Controller come into play.
The Controller does two big things; interacts with the database through Models and renders the webpage from Views.
Let's take a step back... could you imagine this Controller with the routes added in too? What if you have ten-fold the routes and controller modules... this is why separating the steps into their own places just makes sense! If you need to find something specific you know where to look or you can even follow the code around the different files because they leave breadcrumbs on where to look next.
So we're in the todosController
and need to look at the getTodos
.
The getTodos
Controller uses the Todo
Model to gather all of the documents in the database, and it also counts all the documents where completed: false
. With the database information gathered through the Model, the Controller then uses the Views to render the todos.ejs
file for the user.
I know... I know. It's time to get into the details.
Models
The Todo
Model we'll be looking at includes a Mongoose schema. Now you may be asking what a schema is... In simple terms, it is like a blueprint for creating documents in MongoDB. It defines the structure of the documents, including the types of data that can be stored in each field, default values, and how the data should be validated. Think of it as a template that tells MongoDB what kind of data to expect and how to handle it.
So looking at this Model and the schema within, you can see that our documents in the database collection have two properties: todo
and completed
and each of these has a defined type and if they're required. This is a great way to know the kind of data we're working with and what can be submitted to and requested from the database, especially if you don't have access to the database yourself.
When a document in the database matches the format stated within the schema it will be associated with the Model, which is important when we look at the Controller. You can see that the find()
and countDocuments()
work with the Todo
Model to get documents that match the schema from the database.
And once we have that information from the Database we use it to render the todos.ejs
from our Views.
Views
This is where we render what the user will see and interact with on their end. We inject the documents from the database (which were gathered through the Model), this allows the user to interact with the data displayed in the DOM. The Views file doesn't actually know where that data came from or how it was processed; it just displays what it's instructed by the Controller.
Above is a code snippet from the todosController
that renders the View's todos.ejs
and passes in the database information with todos
and left
variables.
This is the Views todos.ejs
file, you can see here we are generating an unordered list with the database information that was passed in by the todosController
with the todos
variable. It uses the document's ID in the database to create each <li>
and checks if it is completed
to set the class for styling. We also use the left
variable to create a tally of how many items are not complete.
Views are also an area where using MVC can shine. If you wanted to use a different templating engine, React, Vue, etc, all you would need to do is change the Views file. There wouldn't be a need to update any other files as it's all been abstracted from each other.
Summary: The TL;DR
So to sum up the movement around this to-do application this is how it goes:
- The user submits a request to the
/todos
route. -
server.js
: looks at the request and sends it to the appropriate Route. -
Routes
: looks at what kind of request was made and on what path it was for then sends it to the appropriate Controller. -
Controller
: Utilizes the Model and/or View to complete the request. -
Model
: Uses a schema to find the associated database documents needed by the Controller. -
View
: Renders the appropriate file into the DOM as instructed by the Controller. This may or may not include database documents.
MVC is a powerful design pattern that simplifies application development by setting up your code so everything is less chaotic. It separates concerns, supports scalability and maintainability, facilitates team collaboration, and offers flexibility in development and maintenance processes.
In a nutshell, Model View Controller is a friendly guide that makes coding less of a headache.
Top comments (0)