Building Express.js project by Utilizing MVC Pattern
Introduction
Continuing from the previous article on getting started with Express.js: Express.js Basic CRUD Todo list, Express provides a convenient and elegant API for handling requests. However, as the scale grows, having all code such as routes, business logic, and data in one app.js
is not ideal. This article introduces using the MVC architecture to separate code for better maintainability.
What is MVC
MVC (Model-View-Controller) is a widely used architectural pattern that divides the logic of an application into three main parts:
- Model: Responsible for handling data-related logic. Manages the business logic of application data and interacts with the database.
- View: Responsible for displaying data. Manages the presentation of data and typically does not perform any business logic processing. Its role is to present data obtained from the Model in an appropriate format.
- Controller: Responsible for handling user requests and deciding how to respond. Manages the Model and View, receives requests from the View, processes them through the Model, and then returns the results to the View. In simple terms, the Controller controls the flow of data and is responsible for the business logic of the application.
Through this approach, the MVC architecture achieves a clear separation of code, allowing different parts to focus on their specific functions and be maintained independently. This makes it easier for developers to develop, test, and maintain, especially as the application scales.
Understanding Existing Issues
For example, in the existing app.js
: “Edit Todo Code Snippet by ID,” we find that all logic is mixed together, such as routes, business logic, and DB communication. Can we reference the MVC pattern to break down the code into different responsibilities for easier future management?
1. Dividing Different Responsibility Code Files
For example, an API for todo items can be managed in separate folders for different responsibilities. Naming is not fixed; some may name them todos.model.js
, todos.controller.js
, etc., for easy differentiation of purposes:
2. Routes
Additionally, initially register the routes related to routes/todos.js
in app.js
Middleware. Specifically, use express.Router, so that all todoRouter
will be prefixed with the /api/todos
path.
3. Controllers
A simple object containing the editTodo
method can be called:
4. Models
A simple object containing the edit
method can be called, primarily interacting with the database (this example does not use a database, using program execution internal variables as an example):
Summary
Through the examples in this article, we refactored a centralized Express application into a modular design that follows the MVC architecture, clearly delineating the responsibilities between the data layer (Model), business logic layer (Controller), and routing layer (Route). This design not only enhances the readability and maintainability of the code but also lays a solid foundation for team collaboration and project expansion.
- Single Responsibility: Each module focuses on completing its specific function, avoiding code mixing issues.
- Easy to Test: Each layer module can be tested individually, reducing the complexity of testing.
- Modular Development: Team members can independently develop Model, Controller, or Route, improving development efficiency.
- Good Scalability: As the application grows, the MVC structure makes adding features and optimizations more intuitive and controllable.
Although this is a simplified example suitable for beginners, actual projects may also need to consider data validation, security, error handling, and multi-layer architecture (such as service layers) design.
Further Reading
- 27-minute demonstration of MVC architecture | Hex School | 2023 Ironman Competition #3 - Hex School
- Project structure for an Express REST API when there is no “standard way” - Corey Cleary