昨天我完成了 Todo API 的 CRUD,但資料還只是存在記憶體陣列裡,伺服器一重啟就全部消失。
今天要進一步把資料存進 MongoDB,讓 API 有「持久化」的能力。
傳統的資料庫像 MySQL、PostgreSQL 是 關聯式資料庫(SQL),資料存成一張張的表格。
MongoDB 則是 NoSQL 文件型資料庫,每筆資料是一個 JSON 文件,放在集合(Collection)裡。
舉例:Todo 清單在 MongoDB 會長這樣:
{
"_id": "651234abcd1234",
"task": "學 Node.js",
"done": false
}
在本機(或雲端 Atlas)安裝 MongoDB,然後在專案安裝套件:
npm install mongoose
Mongoose 是一個 ODM(Object Data Modeling)工具,可以讓我們用物件的方式操作 MongoDB。
import mongoose from "mongoose";
export async function connectDB() {
try {
await mongoose.connect("mongodb://127.0.0.1:27017/todo_app");
console.log("✅ 已連線到 MongoDB");
} catch (err) {
console.error("❌ MongoDB 連線失敗", err);
process.exit(1);
}
}
Schema 就像「資料的結構定義」。
import mongoose from "mongoose";
const todoSchema = new mongoose.Schema({
task: { type: String, required: true },
done: { type: Boolean, default: false }
});
export const Todo = mongoose.model("Todo", todoSchema);
把昨天的 app.js
修改,讓它真正存取資料庫。
import express from "express";
import { connectDB } from "./db.js";
import { Todo } from "./models/Todo.js";
const app = express();
const port = 3000;
app.use(express.json());
// 連線到 MongoDB
connectDB();
// GET /todos → 查詢所有資料
app.get("/todos", async (req, res) => {
const todos = await Todo.find();
res.json(todos);
});
// POST /todos → 新增一筆資料
app.post("/todos", async (req, res) => {
const { task } = req.body;
if (!task) {
return res.status(400).json({ error: "task 欄位必填" });
}
const todo = new Todo({ task });
await todo.save();
res.status(201).json(todo);
});
app.listen(port, () => {
console.log(`伺服器已啟動:http://localhost:${port}`);
});
curl -X POST http://localhost:3000/todos \
-H "Content-Type: application/json" \
-d '{"task": "寫 Day 15 文章"}'
輸出:
{
"_id": "6512abcd1234ef567890",
"task": "寫 Day 15 文章",
"done": false,
"__v": 0
}
curl http://localhost:3000/todos
輸出:
[
{ "_id": "6512abcd1234ef567890", "task": "寫 Day 15 文章", "done": false, "__v": 0 }
]
今天第一次把 API 接上真正的資料庫,感覺很不一樣: