昨天我們完成了一個 記憶體版的 Todo CRUD API,但資料只存在程式執行時,伺服器一關閉資料就消失。在真實專案中,我們需要 資料庫(Database) 來持久儲存資料。今天我們將使用 MongoDB 搭配 Mongoose 來改寫 Todo API。
npm install mongoose
修改 index.js:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const port = 3000;
app.use(express.json());
// 連線到 MongoDB
mongoose.connect('mongodb://127.0.0.1:27017/todo_api')
.then(() => console.log('✅ Connected to MongoDB'))
.catch(err => console.error('❌ MongoDB connection error:', err));
// 定義 Todo Schema
const todoSchema = new mongoose.Schema({
task: { type: String, required: true },
done: { type: Boolean, default: false }
});
// 建立 Model
const Todo = mongoose.model('Todo', todoSchema);
// ===== Create =====
app.post('/api/todos', async (req, res) => {
try {
const todo = new Todo({ task: req.body.task });
const saved = await todo.save();
res.status(201).json(saved);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
// ===== Read =====
app.get('/api/todos', async (req, res) => {
const todos = await Todo.find();
res.json(todos);
});
app.get('/api/todos/:id', async (req, res) => {
try {
const todo = await Todo.findById(req.params.id);
if (!todo) return res.status(404).json({ error: 'Todo not found' });
res.json(todo);
} catch (err) {
res.status(400).json({ error: 'Invalid ID format' });
}
});
// ===== Update =====
app.put('/api/todos/:id', async (req, res) => {
try {
const updated = await Todo.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true } // 回傳更新後的資料
);
if (!updated) return res.status(404).json({ error: 'Todo not found' });
res.json(updated);
} catch (err) {
res.status(400).json({ error: 'Invalid ID format' });
}
});
// ===== Delete =====
app.delete('/api/todos/:id', async (req, res) => {
try {
const deleted = await Todo.findByIdAndDelete(req.params.id);
if (!deleted) return res.status(404).json({ error: 'Todo not found' });
res.json(deleted);
} catch (err) {
res.status(400).json({ error: 'Invalid ID format' });
}
});
app.listen(port, () => {
console.log(`🚀 Server running at http://localhost:${port}`);
});
node index.js
POST http://localhost:3000/api/todos
Body: { "task": "寫 Day 18 文章" }
GET http://localhost:3000/api/todos
PUT http://localhost:3000/api/todos/<id>
Body: { "done": true }
DELETE http://localhost:3000/api/todos/<id>
今天我們把 API 從記憶體升級到 MongoDB ,實現了完整的 CRUD + 永續儲存 。至此,我們的 Todo API 已經達到一個「可實際使用」的基本版本。