Express Zod 驗證:打造型別安全且強健的 API 請求校驗
後端開發中有一句至理名言:「永遠不要相信客戶端傳過來的任何資料」。為了確保系統安全、資料一致性並避免因格式錯誤導致的崩潰,我們需要強大的驗證工具。在現代 Node.js 與 TypeScript 生態系中,Zod 是目前公認最優雅、功能最全的選擇。
為什麼選擇 Zod?
- 開發者友好:宣告式的 Schema 定義,語法直觀易懂。
- 型別推導:能自動從 Schema 生成 TypeScript 型別,減少重複定義。
- 功能豐富:支援自定義報錯訊息、資料轉換 (Transform) 與複雜的邏輯校驗 (Refine)。
安裝與基礎用法
npm install zod
定義驗證 Schema
const { z } = require('zod');
const loginSchema = z.object({
// 鏈式呼叫:必須是字串、符合 Email 格式、帶有自定義錯誤訊息
email: z.string().email('電子郵件格式不正確'),
password: z.string().min(8, '密碼長度至少需 8 位'),
});
在 Express 路由中實戰
你可以使用 safeParse 進行不拋出異常的驗證,這在處理邏輯分支時非常方便。
app.post('/api/login', (req, res) => {
const result = loginSchema.safeParse(req.body);
if (!result.success) {
// 驗證失敗,回傳結構化的錯誤資訊
return res.status(400).json({
errors: result.error.flatten().fieldErrors,
});
}
// 驗證成功,result.data 是經過校驗且乾淨的資料
const { email, password } = result.data;
res.send('驗證通過,準備登入...');
});
進階:封裝驗證中間件 (Middleware)
為了保持路由處理器的整潔,我們建議將驗證邏輯封裝成中間件。
const validate = (schema) => (req, res, next) => {
try {
// parse 會在驗證失敗時直接拋出 ZodError
schema.parse({
body: req.body,
query: req.query,
params: req.params,
});
next();
} catch (err) {
// 配合先前提過的「集中式錯誤處理器」
next(err);
}
};
// 使用時極簡且優雅
app.post('/api/profile', validate(profileSchema), (req, res) => {
res.send('資料格式完全正確!');
});
Zod 的殺手鐧功能
.default():若欄位缺失,自動補上預設值。.transform():在驗證的同時轉換資料(例如將字串轉為數字)。.refine():執行自定義邏輯(例如檢查「密碼」與「確認密碼」是否一致)。
const passwordSchema = z
.object({
password: z.string(),
confirm: z.string(),
})
.refine((data) => data.password === data.confirm, {
message: '兩次輸入的密碼不一致',
path: ['confirm'],
});
總結
- 安全第一:在資料進入資料庫或核心邏輯前,必須經過 Schema 驗證。
- 自動化:利用 Middleware 模式,讓驗證變成一道自動閘門。
- Zod 不僅是驗證器,更是你定義系統資料模型 (Model) 的基石。