JSON 教程

JSON Schema 是什麼?用法、範例與完整教程(2026)

閱讀約 12 分鐘

處理 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 專案為例,完整流程可以拆成四步:

  1. 定義 Schema:在倉庫中維護 schemas/user.json,與 OpenAPI 或介面文件同步版本。
  2. 編寫範例:提供一份合法與一份非法樣例,作為單元測試 fixtures。
  3. CI 整合:在 PR 流水線裡校驗 Mock 響應與 Schema 是否匹配,防止欄位被意外刪除或改名。
  4. 執行時兜底:服務端在接收請求體時執行 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 並接入校驗,再逐步擴充到全專案。

延伸閱讀

更新日誌: 初稿發布