JSON Schema 讓 Postman 測試只需一次斷言,就能將回應主體與嚴格、結構化的契約進行比對,省去數十次屬性檢查。若要從真實回應在 Postman 中建立 JSON Schema,最快的做法是將該回應送入 Draft 2020-12 產生器,檢視推斷出的必填欄位、可空性與陣列,再將產生的 schema 貼入 Postman 測試腳本。產生器不會連線 registry、不會執行驗證器,也不會上傳樣本,因此整個工作流程在 API 開發期間保持可預測。以 Draft 2020-12 建立的 Postman 測試會接受格式正確的 schema,並在測試結果面板中呈現每一處不符,這也是為何多數團隊現在跳過手寫 schema,直接從產生器開始。這個做法也能讓 schema 文字在不同版本間保持穩定,因為產生器對相同輸入具有確定性。
本指南涵蓋 JSON Schema Generator 會檢視哪些內容、如何在三個步驟內將 Postman 回應樣本轉為 Draft 2020-12 schema,以及在將其套用至 Postman 測試前該如何閱讀輸出結果。它也會逐步說明 Postman 使用者實際需要的脈絡:包含具體步驟的章節,說明如何將產生的 schema 接入 Postman 請求測試。目標方言 URI 為 https://json-schema.org/draft/2020-12/schema,在依賴其斷言前,請先確認您選擇的驗證器支援該方言。

Draft 2020-12 Schema 為 Postman 測試帶來什麼
Postman 測試腳本是在請求完成後執行的 JavaScript。沒有 schema 時,您只能使用 pm.response.json() 與硬編碼檢查,一次斷言一個欄位。有了 schema,您就能在單一呼叫中斷言形狀、型別與是否存在。schema 是純文字,可存放在 Postman 環境變數或 Collection 層級變數中,並透過 Collection Runner 與 CI 執行階段隨著您的請求一起傳遞。
Draft 2020-12 是 JSON Schema Generator 所輸出的方言。較舊版本的 Postman 內建 tv4(Tiny Validator for JSON Schema),而現代的 Postman 測試腳本可呼叫 ajv,ajv 在設定完成後支援 Draft 2020-12。方言很重要,因為有些在 Draft 4 之後新增的關鍵字行為不同,而且產生器的開放物件政策只有在搭配會將缺失的 additionalProperties 視為「允許」的驗證器時才有意義。
產生器從回應樣本中檢視哪些內容
產生器會剖析一個嚴格的 JSON 值,並以遞迴方式走訪。JSON 字串、安全整數、其他數字、布林值與 null 各自對應到相應的 JSON Schema 型別。陣列會輸出根據每個觀察到的元素所推斷出的 items schema,而空陣列則會產生空的 items schema,因為無法合理推論任何元素限制。當兩個相容的數字型別同時出現時,產生器會將 integer 擴大為 number;若型別不相容,則會退而採用確定性的 anyOf 分支,使 schema 仍能接受兩種形狀。
物件會輸出 type、properties 與 required。在每個合併後的物件樣本中都有出現的屬性會被加入 required 陣列。只要有任一物件缺少的屬性,就會從 required 中省略,即使它在多數樣本中都出現。產生器會完整保留屬性名稱,包括標點符號以及形似原型鏈的拼寫,因此您貼上的內容就是實際產生的內容。重要的是,產生器刻意省略 additionalProperties,讓物件保持開放。單一樣本無法證明未出現的鍵是被禁止的,因此 schema 會接受這些鍵,直到您權威性的契約另有規定為止。
產生器刻意不做的事同樣重要。它不會推斷 format、pattern、enum、const、minimum、maximum、multipleOf、長度、唯一性、描述、預設值、範例、棄用、readOnly、writeOnly、內容編碼、參考、錨點、ID、條件式邏輯、unevaluated properties 或商業語意。請僅依據有書面記載的需求新增這些內容。本頁將此視為結構化的樣本推斷,而非 schema 探索。
| 在 Postman 樣本中觀察到的內容 | 推斷的關鍵字 | 產生器輸出的內容 |
|---|---|---|
| 字串值 | type | "string" |
| 安全整數 | type | "integer" |
| 其他數字(浮點數、大整數) | type | "number" |
| 布林值 | type | "boolean" |
| null 與具型別 schema 並存 | type | type 陣列中除了原本的型別外,還包含 "null" |
| 相容的混合數字(integer + number) | type 擴大 | "number" |
| 同一位置出現不相容的型別 | anyOf | 每個型別各一個確定性的 anyOf 分支 |
| 含有可觀察元素的陣列 | items | 根據每個元素推斷出的 items schema |
| 空陣列 | items | 空 schema |
| 在每個合併後物件中都出現的屬性 | required | 屬性加入 required 陣列 |
| 在任一物件中缺少的屬性 | (省略) | 不會加入 required |
| 任意大小的物件 | type、properties、required | 具有開放 additionalProperties 的物件 schema |
從 Postman 回應樣本產生 Schema
這是核心工作流程。開啟 JSON Schema Generator,貼上從 Postman 擷取到的具代表性回應,並檢視結果。
- 從 Postman 擷取嚴格的 JSON 回應。送出請求後,從 Body 分頁複製回應主體。請確認 JSON 是嚴格的:不含註解、不含結尾逗號、沒有 NaN 或 Infinity。若回應看起來雜亂,請先使用 JSON Formatter 進行格式化,讓產生器剖析出與 Postman 在測試時會看到的相同形狀。
- 開啟 JSON Schema Generator 並貼上樣本。該頁面會在目前的分頁中剖析 JSON,不會上傳任何內容。您也可以選擇性地在標題欄位中輸入簡潔的 schema 標題。請選擇具代表性的樣本,而非您看到的第一個回應——若您的端點有時會回傳更豐富的物件,請貼上您希望 schema 接受的最豐富樣本。
- 產生並檢視 schema。點擊 generate。檢查輸出中的必填欄位、直接具型別 schema 上的可空性、根據可觀察元素推斷出的陣列 items,以及樣本混合了不相容型別時所產生的 anyOf 分支。空陣列會產生空的 items schema,而可空屬性則會產生包含 null 的 type 陣列。
- 複製 schema 文字。使用頁面上的複製控制項。對相同輸入而言,輸出具有確定性,因此您可以將其貼入版本控制,日後重新執行產生器以確認沒有任何漂移。
- 以正向與反向實例進行驗證。在將 schema 套用至 Postman 之前,請透過支援 Draft 2020-12 的正式環境驗證器,分別以一個接受的實例與一個拒絕的實例進行測試。JSON Schema Generator 不會執行驗證器,也不會連線 registry;那一步由您負責。
將產生的 Schema 接入 Postman 測試
Postman 會將 schema 讀為字串,並傳遞給 Tests 分頁中的驗證器。您選擇的驗證器決定了它強制執行哪些 Draft 2020-12 關鍵字,因此請挑選您預計部署到正式環境的同一套程式庫,並在此處也使用它。
- 將 schema 存為 Postman 變數。在 Collection 或請求中,開啟 Variables 並新增名為 responseSchema 的變數。將 schema 文字貼入 Current Value 欄位,或將 schema 存成儲存庫中的檔案,並在 pre-request 腳本中使用 pm.collectionVariables.set 載入。變數方式讓 Collection Runner 能在不同環境間重複使用同一個 schema。
- 將驗證器加入 Tests 分頁。較舊的 Draft 4 schema 使用 Postman 內建的 tv4。對於 Draft 2020-12,建議透過沙箱或自行打包的套件使用 ajv:於每次執行時 pm.sendRequest 該套件一次,或以本地副本形式引入。確切的程式碼路徑取決於您的 runner 設定,但契約相同:載入驗證器、剖析 schema 字串、剖析回應,然後進行比對。
- 進行斷言並呈現失敗。當驗證器回報錯誤時,使用 pm.expect 或 tv4 結果物件讓測試失敗。請使用 JSON.stringify 擷取驗證器的錯誤清單,讓 Postman runner 中的失敗訊息能指向確切的屬性路徑。這則單一訊息取代了測試原本需要的十幾次 pm.response.to.have.property 檢查。
- 針對已知正確的回應執行請求。先送出請求一次,確認測試通過。接著對刻意毀損的回應(移除必填欄位、變更型別)送出請求,確認測試以清楚的訊息失敗。兩個方向都很重要;從不失敗的 schema 不是契約,而是裝飾。
在貼入 Postman 之前先閱讀輸出
產生的 schema 是可閱讀、可審閱的,這正是重點。在採用之前,請留意四件事。
必填欄位應符合您權威性契約所承諾的內容。產生器會依據合併後樣本中的出現情形來宣告 required,因此若您只貼上一個回應,required 就只反映那個回應。若您貼上更豐富的樣本,required 會擴大。若某個屬性在正式環境中刻意是可選的,但在您所有的樣本中都有出現,產生器會將其標記為 required,而您的測試將在真實用戶端首次省略它時失敗。
可空的值會以包含 null 的 type 陣列形式呈現。與具型別 schema 並存的 null 屬性會將 null 加入 type 陣列,同時保留 properties 或 items 不受影響。更複雜的組合——例如某個屬性有時是字串、有時是具有不同形狀的 null——則會退而採用 anyOf。
陣列 items 反映每個觀察到的元素型別。若您的陣列混合了數字與字串,您會看到同時涵蓋兩者的 anyOf 分支。空陣列會將 items 留為空 schema,Postman 會將其解讀為接受任何內容——這是刻意的,因為無法合理推論任何元素限制。
開放物件保持開放。schema 不會包含 additionalProperties: false,因此 Postman 會接受新的鍵。若您希望 Postman 拒絕未知的鍵,請從您權威性的契約中加入封閉物件的關鍵字。
Validate the Schema With the Same Validator Postman Uses
The JSON Schema Generator emits text and stops. It does not run a validator, does not guarantee format assertions, and does not contact a schema registry. Validators interpret keywords differently across libraries, and Draft 2020-12 format behavior is annotation-only unless the chosen implementation enables assertion. Before you publish the schema, run the same schema through the same validator Postman will use, with both an accepted and a rejected instance. The JSON Schema core specification is the source of truth for what each keyword means; if your validator disagrees, your validator needs tuning, not your schema.
The JSON Schema Generator page keeps parsing and inference local to your tab, so the schema you copy is exactly the schema you will paste into Postman. The limits you should keep in mind are 500,000 input characters, 50,000 values, 40 nesting levels, and 1,000,000 output characters. Boundary failures emit no partial schema, so if your response sample is unusually large or nested, trim it or break it into smaller schemas rather than rely on the tool to recover.
Edge Cases That Break the First Postman Validation
A few failure modes show up the first time teams adopt this workflow. The schema passes in Postman but fails in production because the production validator uses a different ajv configuration — fix by testing the same schema through the same validator in both places. The schema fails because Postman returned the response as a string and you forgot JSON.parse before validation — fix by parsing once at the top of the Tests tab. The schema fails because Postman dropped a property on serialization — fix by validating the raw response before any Postman-side reshaping.
Strict JSON is required by the generator, so comments, trailing commas, NaN, Infinity, undefined, BigInt, and JavaScript literals all fail. JavaScript parses the sample number before inference; only safe integers become integer, which avoids a false exactness claim for larger rounded values. Precision-sensitive decimals and identifiers should travel as strings plus application validation, not as JSON numbers the generator will type as integer or number.
If the body captured from Postman is hard to read at a glance, format the response sample for readability before you paste it. That guide covers indentation choices and quick sanity checks that line up with what the generator expects to parse, and it avoids surprises when the validator in Postman later rejects a subtle malformed value.
Related reading: Is JSON to CSV Safe to Use Online? A Privacy-First Guide.