在 Node.js 中開始使用 JSON Schema
最初發佈於 simonplend.com。
為您的 Node.js 應用程式建立請求驗證的第一步是找到一種建立彈性驗證規則的方法。當您嘗試選擇要使用的驗證函式庫時,通常會比您預期的更困難。它們彼此之間都不同,而且不清楚其中一個比另一個有什麼好處。
也許您之前曾嘗試建立自己的自訂驗證,但它開始感覺雜亂且難以維護。您想要設置一些可靠的驗證,然後繼續在您的應用程式中建立令人興奮的新功能。為什麼添加驗證會如此令人頭痛?!
在本文中,我們將學習 JSON Schema 規範如何幫助我們建立彈性的驗證規則。我們將編寫一個 schema,描述我們期望資料採用的格式,然後我們將編寫一些 JavaScript,使用 Ajv 驗證器函式庫根據它驗證我們的資料。
讓我們開始吧!
強大的驗證組合
JSON Schema 規範定義了一種基於 JSON 的格式,用於描述 JSON 資料的結構。這包括驗證關鍵字,例如 type
、required
和 properties
。這些關鍵字允許我們建立我們期望資料採用的格式的定義。這是一個「schema」。它可以像這樣簡單
為了根據 schema 驗證資料,我們需要使用一個實作 JSON Schema 規範的驗證器函式庫。Ajv (Another JSON Schema Validator) 函式庫是最受歡迎的客戶端和伺服器端 JavaScript JSON Schema 驗證器,每週從 npm 下載超過 5000 萬次。
讓我們動手看看使用 JSON Schema 和 Ajv 驗證資料是什麼樣子。
如需更詳細的 JSON Schema 介紹,請查看部落格文章 5 分鐘了解 JSON Schema。
建立 schema 並驗證資料
首先,我們需要執行命令 npm install ajv
來安裝 Ajv 函式庫。
然後我們可以直接開始定義 JSON schema。它描述了我們期望的結構和類型
1const iceCreamSchema = {
2 type: "object",
3 properties: {
4 flavour: { type: "string" },
5 price: { type: "number" },
6 stock: { type: "number" },
7 },
8 required: ["flavour", "price", "stock"],
9};
現在我們將定義要驗證的資料
1const iceCreamData = {
2 flavour: "Pistachio",
3 price: 1.99,
4 stock: null,
5};
然後我們將導入 Ajv 函式庫並建立一個新的 Ajv 實例
1import Ajv from "ajv";
2
3const ajv = new Ajv();
並使用它來根據我們的 schema 驗證資料
1const isDataValid = ajv.validate(iceCreamSchema, iceCreamData);
最後,我們將添加一些程式碼來處理驗證結果
1if (isDataValid) {
2 console.log("The ice cream data is valid! 🍨");
3} else {
4 console.error("The ice cream data is invalid:", ajv.errors);
5}
當我們將此程式碼放在一起並執行時,我們會得到以下輸出
1The ice cream data is invalid: [
2 {
3 instancePath: '/stock',
4 schemaPath: '#/properties/stock/type',
5 keyword: 'type',
6 params: { type: 'number' },
7 message: 'must be number'
8 }
9]
很棒,不是嗎?
好的,我們建立了一個描述我們期望的結構和類型的 schema,根據它驗證了資料,並處理了任何驗證錯誤。到目前為止一切順利!
來自編輯的注意事項:在 AJV 的最新主要版本中,引入了「嚴格模式」,預設情況下啟用,有時在使用有效的 JSON Schema 時會拋出異常。如果您遇到與嚴格模式相關的錯誤問題,請查看文件,以了解如何停用它,甚至停用特定規則。我們認為這作為 linter 功能可能會更好,但是它確實有助於防止 schema 編寫中出現意外錯誤。- Ben Hutton
作為最後一步,我們將了解如何潛在地改進建立 JSON schema 的方式。
Schema 產生
JSON schema 是定義驗證規則的一種表達方式,但是「手動」編寫 schema 有時會有點多。有一個方便的函式庫叫做 fluent-json-schema,可以幫助我們產生 JSON schema。讓我們試試看。
請注意,雖然使用工具定義要轉換為 JSON Schema 的驗證規則可讓您掌控,但其他產生 JSON Schema 的方法,例如從您的實例資料產生,通常會讓您得到不完整或有時不正確的 JSON Schema。其他方法可能更適合稱為「腳手架」而不是「產生」,因為您將擁有基礎知識,但在它完整且可用之前仍然有工作要做。
首先,我們需要透過執行命令 npm install fluent-json-schema
來安裝該函式庫。然後我們可以導入它並使用它來產生我們的 schema
1import S from "fluent-json-schema";
2
3const iceCreamSchema = S.object()
4 .prop("flavour", S.string().required())
5 .prop("price", S.number().required())
6 .prop("stock", S.number().required())
7 // This method call returns the generated schema as an object.
8 .valueOf();
如果我們 console.log
iceCreamSchema
物件,我們可以看到我們產生的 JSON schema
你會注意到這個產生的 schema 幾乎與我們之前「手動」編寫的 iceCreamSchema
相同。我們可以將我們手寫的 schema 替換為這個產生的 schema,驗證行為會跟之前一樣。
如果我們使用 TypeScript 來編寫應用程式,TypeBox 函式庫是 fluent-json-schema
的絕佳替代方案。
Schema 的產生取決於個人偏好:有些人喜歡「手動」編寫原始 JSON schema,而另一些人則喜歡使用函式庫來協助產生。兩種都試試看,然後選擇最適合你的方法。
親自試試看
- 在 GitHub 上瀏覽程式碼
- 使用 StackBlitz 在你的瀏覽器中執行程式碼 (適用於 Chrome、Edge 或 Brave 瀏覽器)
- 接受驗證程式碼的挑戰! 🏆
總結
我們可以將 Ajv 作為獨立函式庫使用,或者將它與我們用來建置 Node.js 應用程式的框架整合。有些 Node.js 框架甚至提供以 Ajv 為基礎的 JSON Schema 驗證內建功能。
當我們結合 JSON Schema 和 Ajv 時,我們就有了一個彈性的解決方案,可以在我們的 Node.js 應用程式中實作驗證。
- 一次學習,隨處使用。 JSON Schema 規格是跨平台的,而且每個流行的程式設計語言都有可用的驗證函式庫。我們不會被鎖定在某個函式庫、框架或語言中。一旦我們學會了 JSON Schema 的基本原理,我們就可以在任何地方使用它。
- 可攜性。因為 JSON Schema 是跨平台的,即使我們決定以另一個框架或語言重寫我們的應用程式,我們也可以帶著我們的 schema 一起走。
- 速度。在底層,Ajv 會將我們的 JSON schema 編譯為 JavaScript 程式碼。這提高了針對 schema 重複驗證資料的效能。例如,當我們的 Node.js 應用程式啟動時,Ajv 可以編譯 schema。然後,應用程式接收到的 HTTP 請求資料可以根據預先編譯的 schema 進行驗證。
- 活躍且支援的社群。在 Slack 上有一個活躍的社群,他們很樂意提供協助(JSON Schema 網站上有一個連結可供你加入)。
延伸閱讀
如果你想了解更多關於 JSON Schema 的資訊,你可能會發現這些連結很有幫助
- 如何在你的 Express API 中處理請求驗證。如果你正在使用 Express Node.js 框架,我撰寫了這份指南來幫助你將 Ajv 函式庫整合到你的應用程式中。
- Fastify 框架驗證文件。Fastify Node.js 框架整合了 Ajv 函式庫,使得使用 JSON Schema 添加驗證變得非常簡單。
- 理解 JSON Schema。一本免費的線上書籍,將教你 JSON Schema 的基礎知識。也提供 PDF 格式供離線閱讀。
- JSON Schema 速查表。我製作了這份速查表 PDF,作為 JSON Schema 驗證關鍵字的方便參考。在你撰寫 schema 時,隨時可以使用它來協助你。
照片由 Manik Rathee 在 Unsplash 上提供。