iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0
Modern Web

現在就學Node.js系列 第 15

Express.js MVC 架構

  • 分享至 

  • xImage
  •  

為什麼要學 MVC?

當專案小時候,一支 app.js 搞定一切還算輕鬆。

但隨著功能越來越多,程式碼會變得難以維護。

👉 MVC 架構的優勢:

  • M(Model):資料層,負責和資料庫溝通。
  • V(View):視圖層,通常在 API 專案中就是 JSON 回應。
  • C(Controller):邏輯層,負責處理請求、呼叫 Model,並回傳 Response。

這樣一來,每一層都有清楚分工,程式更容易維護與擴充。

我們繼續將昨天的專案修改成 MVC的架構!


📂 專案結構

project/
├── app.js
├── routes/
│   └── notes.js
├── controllers/
│   └── notes.js
└── models/
    └── noteModel.js

1️⃣ app.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");
});

2️⃣ models/noteModel.js — Model 層

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;
}

3️⃣ controllers/notes.js — Controller 層

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();
}

4️⃣ routes/notes.js — Router 層

保持乾淨,負責路由與 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

小結

  • MVC 架構讓程式碼分工更清楚:
    • Router → API 路由設定
    • Controller → 業務邏輯
    • Model → 資料存取
  • 這是 Express 專案最常見的結構之一。
  • 後續只要替換 Model,就能快速接上 MongoDB / MySQL,而不用動到 Controller 或 Router。

上一篇
Express.js Router 拆分 — 讓 API 更有架構 - Day14
系列文
現在就學Node.js15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言