6. Model-View-Controller Architecture
Last updated
Last updated
As your application grows in scale and scope, it is important to have a consistent approach for organizing its many components.
In this lesson, we'll learn how to implement one of the most popular patterns called the Model-View-Controller Architecture.
Table of Contents:
In the last lesson, we built a RESTful API that lets users manage a list of fellows. They can:
(Create) Add a new fellow to the list
(Read) Get all fellows
(Read) Get a single fellow
(Update) Change the name of a fellow
(Delete) Remove a fellow from the list
In that application, all of the logic was built into the serer/index.js
file. While we have some organization within the file, separating the concerns of one file into multiple files will enable our application to scale without becoming a "monolith"
While there are many approaches for organization and separation of concerns, one highly popular approach is called the Model-View-Controller (MVC) Architecture.
This architecture pattern organizes our code into three distinct pieces:
The Models are responsible for storing and managing the data of an application. They provide an interface (a set of methods) for interacting with that data in a predictable manner.
The Views are responsible for rendering the data of an application. They provide user-interfaces with buttons, forms, and other components that allow the user to see and request changes to the data.
The Controllers are responsible for managing interactions between the views and models. They process user inputs from the views, invoke the appropriate methods of the models, and send response back to the views to be updated.
With our current application structure, we already have clear separation between the views (our frontend React application) and the controllers (our Express endpoints/controllers).
However, our controllers and model are intertwined since our controllers directly interact with the database (the fellows
array). That is, they both handle the logic of parsing request inputs AND handle the logic of managing the data.
We need to create a separate model that focuses solely on managing the friends
database and provides methods for our controllers to use.
To create an MVC architecture, take a moment and build the following file structure for your server application.
index.js
builds the app
, configures middleware, and sets the endpoints. However, the controllers are now imported.
controllers/fellowControllers.js
defines all of the controllers for endpoints relating to fellow data. Each set of data should have its own controllers file.
models/Fellow.js
defines a model for managing fellow data. This model is used exclusively by the fellow controllers. Each set of data managed by the server should have its own model.
By separating our code in this way, we show the separate "layers" of the application.
Before we build a model, do the following:
Move all of your controller functions into the controllers/fellowControllers.js
file
Export them as an object using module.exports = { /* list controller methods*/ }
Import the collection of controllers into server/index.js
using require(./controllers/fellowControllers.js)
To build a separate model layer to handle only data management logic, we will:
Make a models/Fellow.js
file.
Inside, export a Fellow
with static
methods for each action needed by the controllers.
Move the fellows
"database" inside so the only way to access its data is through the model's interface.
With the Fellow
model, we now leave managing the data to the model and let the control just focus on parsing the request and sending the response.
Build a Song
model and a server application for maintaining a playlist. Each song should have an id
, a title
, and an artist
(at minimum). The model should provide an interface for:
Creating a new song
Getting all songs
Getting a single song
Updating the title or artist of a song
Deleting a song
Then, create an endpoint and a controller for each of these pieces of functionality. The endpoints should follow REST conventions and should all begin with /api
Finally, build a frontend react application that can interact with the songs API that you've built. It should be able to:
Create: Add a new song to the list.
Read: Display a list of all songs.
Read: Display a single song.
Update: Update a single songs's title or artist.
Delete: Delete a single song.
Here is a recommended React Router page structure for your React app:
/
: The homepage which includes:
Form for creating a new song
List of all songs
/songs/:id
: The details of a single song which includes
The title, artist, and ID of the song
A form to submit a new title or artist for the song
A button to delete the song from the list