當專案小時候,一支 app.js
搞定一切還算輕鬆。
但隨著功能越來越多,程式碼會變得難以維護。
👉 MVC 架構的優勢:
這樣一來,每一層都有清楚分工,程式更容易維護與擴充。
我們繼續將昨天的專案修改成 MVC的架構!
project/
├── app.js
├── routes/
│ └── notes.js
├── controllers/
│ └── notes.js
└── models/
└── noteModel.js
import express from "express";
import notesRouter from "./routes/notes.js";
const app = express();
app.use(express.json());
// 掛載路由
app.use("/notes", notesRouter);
app.listen(3000, () => {
console.log(" Server running at http://localhost:3000");
});
Model 負責管理資料,目前先用假資料模擬,之後可以替換成 MongoDB。
let notes = [
{ id: 1, title: "第一則筆記" },
{ id: 2, title: "第二則筆記" }
];
export function getAll() {
return notes;
}
export function create(title) {
const newNote = { id: Date.now(), title };
notes.push(newNote);
return newNote;
}
export function update(id, title) {
const note = notes.find((n) => n.id == id);
if (!note) return null;
note.title = title;
return note;
}
export function remove(id) {
const before = notes.length;
notes = notes.filter((n) => n.id != id);
return notes.length < before;
}
Controller 呼叫 Model,處理請求邏輯。
import * as NoteModel from "../models/noteModel.js";
export function getAllNotes(req, res) {
res.json(NoteModel.getAll());
}
export function createNote(req, res) {
const newNote = NoteModel.create(req.body.title);
res.status(201).json(newNote);
}
export function updateNote(req, res) {
const note = NoteModel.update(req.params.id, req.body.title);
if (!note) return res.status(404).json({ error: "找不到筆記" });
res.json(note);
}
export function deleteNote(req, res) {
const deleted = NoteModel.remove(req.params.id);
if (!deleted) return res.status(404).json({ error: "找不到筆記" });
res.status(204).send();
}
保持乾淨,負責路由與 Controller 的對接。
import express from "express";
import {
getAllNotes,
createNote,
updateNote,
deleteNote
} from "../controllers/notes.js";
const router = express.Router();
router.get("/", getAllNotes);
router.post("/", createNote);
router.put("/:id", updateNote);
router.delete("/:id", deleteNote);
export default router;
[Client 請求]
│
▼
[Router 層] → 決定走哪條路 (GET/POST/PUT/DELETE)
│
▼
[Controller 層] → 負責處理邏輯,呼叫 Model
│
▼
[Model 層] → 負責存取資料(目前是記憶體,之後換 DB)
│
▼
[Response] → JSON 回應給 Client