JSON Schema 是什麼?用法、範例與完整教程(2026)
處理 API 響應或配置檔案時,JSON 語法正確並不代表資料「合法」——欄位缺失、型別錯誤或取值越界,往往要到執行時才會暴露。JSON Schema 正是為解決這類問題而誕生的規範。本文將從定義與使用場景出發,逐步講解基本寫法、常用關鍵字、實戰校驗流程與工具選型,幫助你建立一套可落地的 JSON 資料約束方案。
閱讀前速覽
| 專案 | 說明 |
|---|---|
| 核心問題 | JSON 語法正確,但結構或取值不符合業務約定 |
| 解決思路 | 用 Schema 宣告欄位型別、必填項與約束,再自動校驗 |
| 推薦版本 | Draft 2020-12(生態支援最成熟) |
| 本文覆蓋 | 定義 → 寫法 → 關鍵字 → 實戰 → 選型 → FAQ |
JSON Schema 是什麼?
JSON Schema 是一種基於 JSON 的規範,用來描述「一份 JSON 資料應該滿足什麼條件」。你可以把它理解為資料的型別宣告 + 約束規則:哪些欄位必須存在、每個欄位是什麼型別、字串長度或數值範圍是多少、陣列元素應滿足什麼結構,都可以寫進 Schema 裡。
它本身也是合法的 JSON 文件,只是語義不同——Schema 不承載業務資料,而是描述業務資料的形狀。OpenAPI 3.x 用 JSON Schema 描述請求/響應體;很多 CLI 工具用 Schema 校驗配置檔案;前端表單庫也常用 Schema 驅動校驗邏輯。掌握它之後,你可以在前端、後端、CI 流水線裡複用同一份約束定義,減少「各端各寫一套校驗」的重複勞動。
為什麼需要 JSON Schema?
日常開發裡,JSON.parse() 只能告訴你括號是否配對、引號是否正確。以下情況語法校驗完全無能為力:
- 介面要求
email欄位,但響應裡漏傳了 age應該是整數,客戶端卻傳了字串"25"- 列舉欄位
status出現了約定之外的值"unknown" - 巢狀物件
address.zip不符合郵編格式
JSON Schema 的價值在於:把上述「隱含約定」變成可執行、可共享、可版本管理的宣告。團隊可以在 Code Review 階段就對照 Schema 檢查介面變更,而不是等到聯調或上線後才發現欄位對不上。
JSON Schema 基本用法與範例
最簡 Schema 需要宣告 $schema(使用的規範版本)和根級 type。下面描述一個使用者物件:name 必填字串,age 可選非負整數。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/user.json",
"title": "User",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"description": "使用者姓名"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
},
"email": {
"type": "string",
"format": "email"
}
},
"required": ["name"],
"additionalProperties": false
}
對應合法的資料例項:
{ "name": "張三", "age": 28, "email": "zhang@example.com" }
若傳入 { "age": 28 }(缺少必填 name),或 { "name": "李四", "extra": true }(additionalProperties: false 禁止額外欄位),校驗器會返回明確的錯誤路徑與原因。
常用關鍵字速查
Draft 2020-12 中開發者最高頻的關鍵字如下,寫 Schema 時幾乎都會用到:
| 關鍵字 | 作用 | 範例 |
|---|---|---|
| type | 宣告資料型別 | "string" / "integer" / "object" |
| properties | 物件的欄位定義 | { "id": { "type": "integer" } } |
| required | 必填欄位列表 | ["id", "name"] |
| enum | 限定列舉值 | ["draft", "published"] |
| format | 常見字串格式 | "email" / "date-time" |
| $ref | 引用其他 Schema 片段 | "#/$defs/Address" |
複雜 Schema 建議用 $defs 拆分可複用片段(如 Address、Pagination),再透過 $ref 引用,避免單檔案膨脹。
JSON Schema 與 JSON 語法校驗的區別
兩者解決不同層次的問題,實踐中通常組合使用:
- 語法校驗:括號、引號、逗號是否合法 → 能否
JSON.parse - Schema 校驗:欄位、型別、約束是否符合約定 → 能否透過業務規則
推薦工作流:先把原始文字貼上到 JSONSort 做格式化與語法檢查,確認無誤後再交給 ajv、fastjsonschema 等庫做 Schema 驗證。本地工具處理語法層,Schema 處理語義層,職責清晰。
實戰:API 契約校驗流程
以一個典型的 REST 專案為例,完整流程可以拆成四步:
- 定義 Schema:在倉庫中維護
schemas/user.json,與 OpenAPI 或介面文件同步版本。 - 編寫範例:提供一份合法與一份非法樣例,作為單元測試 fixtures。
- CI 整合:在 PR 流水線裡校驗 Mock 響應與 Schema 是否匹配,防止欄位被意外刪除或改名。
- 執行時兜底:服務端在接收請求體時執行 Schema 校驗,返回 400 與結構化錯誤,而不是把髒資料寫入資料庫。
這套流程的核心收益是變更可感知:介面欄位改動會在 CI 階段被捕獲,而不是依賴人工記憶或聯調時的偶然發現。
JSON Schema 與其他方案對比
| 方案 | 優點 | 侷限 |
|---|---|---|
| JSON Schema | 語言無關、OpenAPI 原生支援、生態成熟 | 複雜規則表達力有限,學習曲線存在 |
| TypeScript 型別 | IDE 體驗好,編譯期檢查 | 僅限 TS 生態,執行時需額外轉換 |
| 手寫 if/else 校驗 | 靈活,無額外依賴 | 難維護、難複用、容易遺漏邊界 |
| Protobuf / Avro | 強型別、高效能序列化 | 需要編譯步驟,不適合純 JSON API 場景 |
若你的 API 已經是 JSON + OpenAPI,JSON Schema 通常是最低摩擦的選型;若全棧 TypeScript 且不需要跨語言契約,可以 TS 為主、Schema 為輔。
JSON Schema 值得投入嗎?
建議投入的場景:
- 對外提供 API,需要與呼叫方共享機器可讀的契約
- 配置檔案結構複雜,希望在部署前攔截格式錯誤
- 多端(Web / 移動端 / 後端)共用同一份資料約束
- 需要在 CI 中自動化檢測介面 breaking change
可以暫緩的場景:
- 只是偶爾格式化或檢視 JSON → 用 JSONSort 即可
- 資料結構極簡且長期不變 → 手寫校驗成本更低
- 團隊無 OpenAPI / 契約測試流程 → 先建立文件習慣再引入 Schema
常見問題(FAQ)
JSON Schema 是什麼?
JSON Schema 是描述 JSON 資料結構與約束的規則集。它本身是一份 JSON 文件,用於宣告欄位型別、必填項、取值範圍等,供校驗器自動判斷資料是否合法。
JSON Schema 和 JSON 有什麼區別?
JSON 承載業務資料;JSON Schema 描述這份資料應該長什麼樣。類比:JSON 是「例項」,Schema 是「模具」。
應該選哪個版本?
新專案優先 Draft 2020-12。舊專案若已使用 Draft-07 / 2019-09,不必強行遷移,除非依賴新版本關鍵字。
如何在本地校驗?
語法層用 JSONSort 格式化與檢查;Schema 層用 ajv(Node.js)、jsonschema(Python)或 VS Code 的 JSON Schema 外掛。
OpenAPI 和 JSON Schema 什麼關係?
OpenAPI 3.x 的請求/響應體定義基於 JSON Schema 的子集並做了擴充。寫好 OpenAPI 文件,本質上就在寫 Schema。
結論
JSON Schema 解決的不是「JSON 能不能解析」,而是「資料是否符合團隊約定」。從定義、寫法到 CI 整合,它的價值在於把隱式規則變成顯式、可執行的契約。建議從一個小型介面或配置檔案入手,寫第一份 Schema 並接入校驗,再逐步擴充到全專案。
延伸閱讀
- JSON Schema 官方規範 權威關鍵字與版本說明
- JSONSort 本地 JSON 工具箱 格式化、語法校驗、Diff — 瀏覽器本地執行
- 部落格全部文章 更多 JSON 開發教程與實踐經驗
更新日誌: 初稿發布