作者 Oghenetega Denedo✏️
架構驗證是任何生產就緒應用程式的必備條件,因為來自使用者或其他外部來源的任何資料都需要符合預先定義的結構或格式,以維護資料完整性並防止應用程式中出現任何意外行為。
通常,當使用者向網站提交表單或透過 HTTP 請求傳送到 API 的有效負載時,開發人員必須對輸入資料進行驗證。然而,手動編寫此驗證邏輯可能會重複且耗時,這不利於開發人員的工作效率。
幸運的是,用於常見開發任務的函式庫在 JavaScript 社群中幾乎不是什麼問題,模式驗證也不例外。
在本文中,我們將透過評估 VineJS 和 Zod 的驗證功能、性能、與工具的整合以及生態系統來比較它們。最後,您會發現,雖然 VineJS 具有出色的性能,但 Zod 的多功能性和強大的 TypeScript 整合使其成為大多數專案的更全面的選擇。
VineJS 是一個現代 JavaScript/TypeScript 模式驗證函式庫,旨在輕量級、易於使用和高效能。
該專案源自 AdonisJS 驗證器程式碼庫,並已升級並作為獨立庫發布。 VineJS 專為在 Node.js 伺服器端環境中使用而構建,尤其是在驗證 API 傳入請求以確保有效負載在進一步處理之前具有預期格式的場景。
VineJS 的一些主要功能包括:
在下一節中,我們將了解其中一些功能如何發揮作用。
讓我們來看看 VineJS 的一些模式驗證功能。
處理使用者輸入或來自外部來源的資料時,驗證字串、數字和布林值等基本資料類型通常是第一步。 VineJS 透過其直覺的 API 簡化了這個過程。
例如,讓我們驗證使用者的年齡:
import vine, { errors } from "@vinejs/vine"; // NOTE: VineJS is ESM only const ageSchema = vine.number().min(18).max(30); try { const output = await vine.validate({ schema: ageSchema, data: 21 }); console.log(output); } catch (error) { if (error instanceof errors.E_VALIDATION_ERROR) { console.log("validation error: age is invalid"); } else { console.log("an unexpected error occurred"); } }
在這個例子中,我們創建了一個簡單的模式來驗證輸入是一個數字,並使用 min 和 max 方法來確保它在 18 到 30 之間。 VineJS 提供了這些額外的驗證規則來使驗證更加精確。
有時,您需要在套用驗證規則之前格式化輸入資料。例如,如果您想確保輸入字串在驗證之前轉換為小寫,您可以在架構中執行此操作:
const usernameSchema = vine .string() .toLowerCase() .minLength(3) .maxLength(15) .regex(/^[a-z0-9_]+$/); console.log(vine.validate({schema: nameSchema, data: "Bruce_Wayne"})) // logs bruce wayne
在此架構中,在檢查其長度和格式之前,使用者名稱會被轉換為小寫。
除了基本模式類型之外,VineJS 還提供物件和陣列的驗證,這使得它對於驗證具有多個欄位的表單或 API 有效負載特別有用。
讓我們看看如何驗證代表使用者個人資料的物件:
const userProfileSchema = vine.object({ name: vine.string().minLength(3), email: vine.string().email(), age: vine.number().min(18).max(65).optional(), }); const output = await vine.validate({ schema: ageSchema, data: { name: "Jane Doe", email: "jane.doe@example.com", age: 29, }, }); // logs { name: 'Jane Doe', email: 'jane.doe@example.com', age: 29 }
在此範例中,我們為使用者設定檔設定了一個架構,其中包含姓名、電子郵件和年齡欄位。
透過使用 vine.object() 方法,我們可以根據給定的規則驗證每個欄位。預設情況下,vine.object 中的所有欄位都是必需的,因此它們必須存在於正在驗證的物件中。但是,我們已使用 option() 方法將年齡字段標記為可選,因此如果缺少該字段,驗證也不會失敗。
陣列也可以類似處理:
const tagsSchema = vine .array(vine.string().minLength(2).maxLength(20)) .minLength(1) .maxLength(10); console.log( await vine.validate({ schema: tagsSchema, data: ["tech", "news", "coding"], }) ); // logs [ 'tech', 'news', 'coding' ]
在此範例中,架構確保陣列中的每個項目都是長度在 2 到 20 個字元之間的字串,並且陣列本身必須包含 1 到 10 個元素。這對於驗證標籤或類別等清單特別有用。
預編譯是 VineJS 的關鍵功能,它將模式轉換為最佳化的 JavaScript 函數,可以重複用於驗證,以幫助減少重複解析和驗證模式的開銷。這在生產環境中非常有用,可以提高效能。
要預先編譯模式,您可以使用 vine.compile() 方法:
const compiledSchema = vine.compile( vine.object({ username: vine.string().minLength(3).maxLength(30), password: vine.string().minLength(8), }) ); // Use the compiled schema to validate data console.log( await compiledSchema.validate({ username: "janedoe", password: "password123", }) );
預編譯對於需要頻繁驗證的模式特別有用,例如高流量 API 端點中的模式。
由於 schema 將被編譯成可重複使用的函數,因此解析和驗證 schema 的重複過程就不再存在,這樣 VineJS 就可以加快驗證過程,使您的應用程式響應更快。
自訂錯誤訊息有助於向使用者提供更清晰的回饋,以便更輕鬆地識別和糾正錯誤。 VineJS 使用其內建的 SimpleMessagesProvider API 將錯誤訊息定義為鍵值對。鍵可以是規則名稱(即 required 和字串)或特定的欄位-規則組合,值是對應的錯誤訊息。
SimpleMessagesProvider API 可以在全域、每個模式層級或在呼叫 validate 方法時進行設定。對於接下來的程式碼範例,我們將在全域範圍內使用該 API。
例如,假設您想要自訂使用者名稱和電子郵件欄位的錯誤訊息:
import vine, { errors } from "@vinejs/vine"; // NOTE: VineJS is ESM only const ageSchema = vine.number().min(18).max(30); try { const output = await vine.validate({ schema: ageSchema, data: 21 }); console.log(output); } catch (error) { if (error instanceof errors.E_VALIDATION_ERROR) { console.log("validation error: age is invalid"); } else { console.log("an unexpected error occurred"); } }
您也可以自訂巢狀欄位或陣列元素的訊息。對於嵌套字段,請使用點表示法:
const usernameSchema = vine .string() .toLowerCase() .minLength(3) .maxLength(15) .regex(/^[a-z0-9_]+$/); console.log(vine.validate({schema: nameSchema, data: "Bruce_Wayne"})) // logs bruce wayne
對於陣列元素,您可以使用通配符 (*) 來定位所有項目或指定索引:
const userProfileSchema = vine.object({ name: vine.string().minLength(3), email: vine.string().email(), age: vine.number().min(18).max(65).optional(), }); const output = await vine.validate({ schema: ageSchema, data: { name: "Jane Doe", email: "jane.doe@example.com", age: 29, }, }); // logs { name: 'Jane Doe', email: 'jane.doe@example.com', age: 29 }
VineJS 還允許您用更用戶友好的標籤替換欄位名稱。當程式碼中的欄位名稱不適合面向使用者的訊息時,這非常有用:
const tagsSchema = vine .array(vine.string().minLength(2).maxLength(20)) .minLength(1) .maxLength(10); console.log( await vine.validate({ schema: tagsSchema, data: ["tech", "news", "coding"], }) ); // logs [ 'tech', 'news', 'coding' ]
除了內建規則提供的功能之外,VineJS 還使開發人員能夠建立自訂驗證規則來滿足您的特定需求。您可以在專案中使用這些自訂規則,方法是將它們實作為獨立函數或將它們整合到預先存在的架構類別中。
在 VineJS 中,自訂規則只是一個更新或驗證欄位值的函數。通常將三個參數傳遞給函數:要驗證的值、規則可能需要的任何選項以及欄位上下文。
例如,讓我們建立一個名為 mongodbId 的自訂規則,用於檢查字串是否是有效的 MongoDB ObjectId:
const compiledSchema = vine.compile( vine.object({ username: vine.string().minLength(3).maxLength(30), password: vine.string().minLength(8), }) ); // Use the compiled schema to validate data console.log( await compiledSchema.validate({ username: "janedoe", password: "password123", }) );
為了讓該規則在 VineJS 模式中可用,我們必須先使用 vine.createRule 方法將其轉換為 VineJS 相容規則:
import vine, { SimpleMessagesProvider } from '@vinejs/vine'; vine.messagesProvider = new SimpleMessagesProvider({ 'required': 'You must provide a value for {{ field }}.', 'email': '{{ field }} needs to be a valid email address.', 'username.required': 'A username is required to continue.', });
為了進一步簡化其使用,您可能需要將 mongodbId 方法直接添加到 VineString 類別中,以從可連結的 API 中受益:
Zod 是一個 TypeScript 優先的模式驗證函式庫,既簡單又強大。它使定義和執行資料結構和驗證規則變得容易,並且它適用於前端和後端應用程式。
Zod 專為 TypeScript 設計,確保 TypeScript 專案的平滑整合和強型別推斷。
Zod 的一些主要功能是:
Zod 讓模式驗證變得簡單且靈活,讓您可以輕鬆處理各種資料類型和驗證需求。它的語法與 VineJS 非常相似,您將在接下來的部分中看到。
Zod 可以很好地處理字串、數字、布林值和日期等基本資料類型。
例如,讓我們建立一個簡單的模式來驗證字串和數字:
import vine, { errors } from "@vinejs/vine"; // NOTE: VineJS is ESM only const ageSchema = vine.number().min(18).max(30); try { const output = await vine.validate({ schema: ageSchema, data: 21 }); console.log(output); } catch (error) { if (error instanceof errors.E_VALIDATION_ERROR) { console.log("validation error: age is invalid"); } else { console.log("an unexpected error occurred"); } }
在此範例中,nameSchema 驗證「Peter Parker」是一個字串並通過,而ageResult 由於年齡低於 18 歲而失敗。
處理物件和陣列時,Zod 可以輕鬆定義資料的形狀。例如,驗證使用者物件和標籤清單可以像這樣完成:
const usernameSchema = vine .string() .toLowerCase() .minLength(3) .maxLength(15) .regex(/^[a-z0-9_]+$/); console.log(vine.validate({schema: nameSchema, data: "Bruce_Wayne"})) // logs bruce wayne
在上面的範例中,userSchema 驗證使用者數據,tagSchema 檢查陣列是否僅包含字串。陣列驗證失敗,因為 123 不是字串。
為了讓驗證回饋更有用且更簡單地識別錯誤,Zod 還支援可設定的錯誤訊息。
例如,如果年齡未滿18歲,您可以設定個人化訊息:
const userProfileSchema = vine.object({ name: vine.string().minLength(3), email: vine.string().email(), age: vine.number().min(18).max(65).optional(), }); const output = await vine.validate({ schema: ageSchema, data: { name: "Jane Doe", email: "jane.doe@example.com", age: 29, }, }); // logs { name: 'Jane Doe', email: 'jane.doe@example.com', age: 29 }
此處,驗證失敗,並拋出錯誤,並顯示自訂錯誤訊息「您必須年滿 18 歲」。
Zod 提供了使用細化方法建立自訂驗證邏輯的靈活性,這使您可以強制執行基本類型檢查以外的規則。
例如要驗證十六進位顏色代碼,僅僅判斷它是否是字串是不夠的;它還需要遵循一定的模式。以下是具體操作方法:
const tagsSchema = vine .array(vine.string().minLength(2).maxLength(20)) .minLength(1) .maxLength(10); console.log( await vine.validate({ schema: tagsSchema, data: ["tech", "news", "coding"], }) ); // logs [ 'tech', 'news', 'coding' ]
在此範例中,使用細化方法新增自訂驗證邏輯,以確定字串是否是由三個或六個字元(#RGB 或 #RRGGBB)組成的有效十六進位顏色代碼。
VineJS 文件的基準測試表明,VineJS 是 Node.js 生態系統中最快的驗證庫之一,在簡單物件驗證和其他驗證方面超越了 Yup 和 Zod。
如 VineJS 文件所示。
圖表顯示,VineJS 提供了卓越的效能,使其成為需要高效能的後端應用程式的良好解決方案。 Zod 運作良好,速度足以滿足大多數用例。
TypeScript 支援在兩者中都非常出色,但 Zod 在設計時考慮了 TypeScript,以使類型推斷更加無縫。 VineJS 也支援 TypeScript,但整合程度不高,這使得 Zod 在 TypeScript 密集型專案中略佔優勢。
有了更多的資源、教學和插件,Zod 擁有了更大、更成熟的社群。然而,儘管 VineJS 較新、資源較少且社群較小,但由於其易於使用的 API 和注重效能的設計,預計它將進一步發展。
使用 VineJS 的主要缺點是它不適用於前端運行時。由於此限制,它不太適合需要客戶端驗證的應用程式。此外,它不支援 CommonJS,這對於使用它的專案來說可能是一個問題。它僅適用於 ECMAScript 模組 (ESM)。
但是,Zod 更通用,支援兩種主要的 JavaScript 模組系統,同時無論您執行程式碼的環境如何,它都能正常運作,這使得它更適合全端專案。
除了 VineJS 和 Zod 之外,對於各種用例,還有一些其他用於模式驗證的程式庫也值得一提。
由於其易於使用,Yup 很受歡迎並經常用於前端驗證,特別是與 React 和 Formik 等工具結合使用時。與 VineJS 或 Zod 相比,它可能無法在複雜的結構中發揮作用,但其可連結的 API 使開發模式變得簡單。
Node.js 後端中經常使用的強大函式庫稱為 joi。儘管它的 API 感覺比 VineJS 和 Zod 的輕量級方法更重,但它提供了更大的靈活性並管理深度嵌套物件的複雜驗證。對於需要複雜驗證的伺服器端應用程式來說,它是完美的。
速度和完整的 JSON 模式合規性是 AJV 的主要優先事項。儘管它缺乏 Zod 或 VineJS 所具有的用戶友好的 API,但它對於驗證 JSON 資料非常有用,尤其是在 API 中。但對於需要高效率的任務,例如驗證龐大的 JSON 資料集,它是理想的選擇。
VineJS 和 Zod 是兩個優秀的模式驗證工具,使用它們都不會出錯,但它們在不同的領域表現出色。如果您仍然不確定要使用哪一個,請在一個小專案中嘗試它們,看看哪一個適合您。快樂編碼!
偵錯程式碼總是一項乏味的任務。但你越了解自己的錯誤,就越容易糾正它們。
LogRocket 讓您以新的、獨特的方式理解這些錯誤。我們的前端監控解決方案追蹤使用者與 JavaScript 前端的互動,使您能夠準確查看使用者的操作導致了錯誤。
LogRocket 記錄控制台日誌、頁面載入時間、堆疊追蹤、帶有標頭正文的慢速網路請求/回應、瀏覽器元資料和自訂日誌。了解 JavaScript 程式碼的影響從未如此簡單!
免費試用。
以上是VineJS 與 Zod 進行模式驗證的詳細內容。更多資訊請關注PHP中文網其他相關文章!