在前一篇中,我們已經讓 Todo API 連接到 MongoDB,並能進行 CRUD 操作。但如果使用者傳入不正確的資料,例如 title 留空、日期格式錯誤,或是欄位根本不存在,這些都可能造成資料庫混亂。因此,今天我們要透過 Schema 設計 與 資料驗證,確保 API 的穩定性與可靠性。
我們在 Day 18 已經建立了 Todo Model。
今天,我們會在 Schema 中加入驗證規則。
// models/Todo.js
const mongoose = require('mongoose');
const todoSchema = new mongoose.Schema({
title: {
type: String,
required: [true, 'Title is required'], // 必填欄位
minlength: [3, 'Title must be at least 3 characters'], // 最小長度
maxlength: [100, 'Title must be less than 100 characters'] // 最大長度
},
description: {
type: String,
maxlength: [500, 'Description too long'] // 限制字數
},
completed: {
type: Boolean,
default: false // 預設值
},
dueDate: {
type: Date,
validate: {
validator: (value) => value > Date.now(), // 驗證日期必須在未來
message: 'Due date must be in the future'
}
}
}, {
timestamps: true // 自動產生 createdAt, updatedAt
});
const Todo = mongoose.model('Todo', todoSchema);
module.exports = Todo;
新增的驗證規則說明
當使用者傳入不合法資料時,Mongoose 會拋出 ValidationError 。
我們需要在 Controller 中捕捉並回應使用者。
// routes/todos.js
const express = require('express');
const router = express.Router();
const Todo = require('../models/Todo');
// 建立 Todo
router.post('/', async (req, res) => {
try {
const todo = new Todo(req.body);
await todo.save();
res.status(201).json(todo);
} catch (err) {
if (err.name === 'ValidationError') {
// 處理驗證錯誤
return res.status(400).json({
error: 'Validation Error',
details: err.errors
});
}
res.status(500).json({ error: 'Server Error' });
}
});
module.exports = router;
POST /api/todos
Content-Type: application/json
{
"title": "Finish API project",
"description": "Complete CRUD with validation",
"dueDate": "2025-12-31"
}
回傳:
{
"_id": "64xxxxxxx",
"title": "Finish API project",
"description": "Complete CRUD with validation",
"completed": false,
"dueDate": "2025-12-31T00:00:00.000Z",
"createdAt": "...",
"updatedAt": "..."
}
POST /api/todos
Content-Type: application/json
{
"description": "Missing title"
}
回傳:
{
"error": "Validation Error",
"details": {
"title": {
"message": "Title is required"
}
}
}
今天我們完成了 Todo API 的資料驗證與 Schema 設計 :