The Model-View-Controller (MVC) pattern is one of the most popular architectural patterns in web development. By dividing an application into three interconnected components — Model, View, and Controller — MVC promotes organized, maintainable, and scalable code. Node.js, with its asynchronous processing and vast ecosystem, is an excellent choice for building MVC-based applications, especially for web and API development. This guide explores the MVC pattern with Node.js, taking you through its benefits and a practical implementation.
The MVC pattern divides an application into three distinct parts:
This separation of concerns helps organize code in a way that’s easy to manage, test, and expand.
Here, we’ll build a simple MVC application using Node.js and Express. Our example will be a basic "Task Manager" that allows users to view, add, and delete tasks.
Start by creating a new Node.js project and installing necessary dependencies.
# Create a project folder mkdir mvc-task-manager cd mvc-task-manager # Initialize Node.js npm init -y # Install Express and other dependencies npm install express ejs mongoose body-parser
Organize the application into models, views, and controllers folders. This structure is essential for an MVC pattern.
mvc-task-manager/ │ ├── models/ │ └── Task.js │ ├── views/ │ ├── index.ejs │ └── tasks.ejs │ ├── controllers/ │ └── taskController.js │ ├── public/ │ └── css/ │ └── styles.css │ ├── app.js └── package.json
The Model represents the data structure in your application. For this task manager, we’ll define a Task model in MongoDB using Mongoose.
// models/Task.js const mongoose = require('mongoose'); const taskSchema = new mongoose.Schema({ title: { type: String, required: true }, description: { type: String }, completed: { type: Boolean, default: false } }); module.exports = mongoose.model('Task', taskSchema);
Here, taskSchema defines our Task model with fields for title, description, and completed.
The Controller handles the application logic, processes user inputs, interacts with the Model, and directs the View to render the data.
// controllers/taskController.js const Task = require('../models/Task'); exports.getTasks = async (req, res) => { const tasks = await Task.find(); res.render('tasks', { tasks }); }; exports.createTask = async (req, res) => { const { title, description } = req.body; await Task.create({ title, description }); res.redirect('/tasks'); }; exports.deleteTask = async (req, res) => { await Task.findByIdAndDelete(req.params.id); res.redirect('/tasks'); };
This controller defines three main actions:
In this example, we use EJS to render HTML views. This will allow us to display task data dynamically in the browser.
Create an index.ejs file for the homepage and a tasks.ejs file to display tasks.
<!-- views/index.ejs --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Task Manager</title> <link rel="stylesheet" href="/css/styles.css"> </head> <body> <h1>Welcome to Task Manager</h1> <a href="/tasks">View Tasks</a> </body> </html>
The tasks.ejs file will render a list of tasks and provide forms for adding or deleting tasks.
<!-- views/tasks.ejs --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Task List</title> </head> <body> <h1>Tasks</h1> <ul> <% tasks.forEach(task => { %> <li><%= task.title %> - <a href="/delete/<%= task._id %>">Delete</a></li> <% }) %> </ul> <form action="/add" method="POST"> <input type="text" name="title" placeholder="Task Title" required> <input type="text" name="description" placeholder="Description"> <button type="submit">Add Task</button> </form> </body> </html>
Define routes in the main app.js file to connect each URL endpoint to the relevant controller function.
// app.js const express = require('express'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); const taskController = require('./controllers/taskController'); const app = express(); app.set('view engine', 'ejs'); mongoose.connect('mongodb://localhost:27017/taskDB', { useNewUrlParser: true, useUnifiedTopology: true }); app.use(bodyParser.urlencoded({ extended: true })); app.use(express.static('public')); // Routes app.get('/', (req, res) => res.render('index')); app.get('/tasks', taskController.getTasks); app.post('/add', taskController.createTask); app.get('/delete/:id', taskController.deleteTask); const PORT = 3000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
To add a bit of styling, create a styles.css file in the public/css/ folder. You can add basic styling to make your application visually appealing.
Start the application using:
node app.js
Visit http://localhost:3000 in your browser. You’ll be able to navigate between views, add new tasks, and delete tasks using the MVC architecture.
The above is the detailed content of Understanding the MVC Pattern with Node.js. For more information, please follow other related articles on the PHP Chinese website!