Python 專案的 Draft 2020-12 JSON Schema 可以從一個嚴格且具代表性的 JSON 值產生,方法是使用 JSON Schema Generator 來推論結構、複製輸出,並使用生產環境中實際使用的 Draft 2020-12 相容驗證器進行測試。產生器會在目前的瀏覽器分頁中於本機處理結構推論。貼上具代表性的嚴格 JSON 值、加入選擇性的標題,然後產生一份可讀的 Draft 2020-12 schema,而不必手動撰寫每個屬性、型別、null 分支和陣列項目規則。它會推論觀察到的物件欄位、巢狀物件、陣列、基本型別、可空性以及欄位是否存在,但不會自行產生 format、範圍、enum、ID 或封閉物件政策。請使用一個能捕捉 Python 應用程式實際輸出變化的酬載形狀。包含多個物件紀錄的根陣列可以揭露一個永遠存在的欄位以及另一個有時缺席的欄位,同時仍算作單一嚴格 JSON 值。請將複製結果視為可審閱的結構草稿:required 僅依據觀察到的存在與否、開放物件行為是有意為之,業務語意仍須來自書面化需求。該頁面不會上傳資料、執行驗證器,也聯絡不到 schema registry,因此驗證必須隨後在您的 Python 工作流程中執行。

create json schema in python
從 JSON 範例在 Python 中建立 JSON Schema

選擇具代表性的嚴格 JSON 範例

請從以嚴格 JSON 匯出的資料開始,而不是使用帶有註解、單引號鍵或結尾逗號的 Python 字典。雖然產生的 schema 是為 Python 專案而設計,產生器僅接受 JSON 語法,並會拒絕這些非 JSON 的形式。範例不需要包含每個可能值,但應反映您希望第一版草稿所描述的欄位、型別、巢狀、null 模式和陣列內容。

當單一紀錄已包含所需變化時,根物件就很實用。物件紀錄的根陣列對必填欄位分析特別有用,因為產生器可以觀察到哪些屬性出現在每個物件中、哪些屬性至少在一個物件中缺席。舉例來說,一個說明性範例可能在每筆紀錄中都包含 idemail,而 nickname 僅出現在其中一筆。巢狀的 settings 物件可以在每筆紀錄中都包含 theme。這類證據能支撐一份可審閱的草稿,而不會假裝範例已窺得整個 API 契約。

若來源來自 Python 且您不確定是否為嚴格 JSON,請先使用 瀏覽器型 JSON 驗證器。它會檢查 JSON 語法並在您花時間從格式錯誤的輸入產生 schema 之前回報結構診斷結果。

產生 Python 就緒的 Draft 2020-12 Schema

一旦範例準備就緒,產生工作流程就很短。同一份草稿接著可以交給 Python 驗證流程,但工具本身並不會執行應用程式碼或驗證器。

  1. 將具代表性的嚴格 JSON 貼到產生器中。請將預期的整個範例保留在同一個值中。若欄位出現與否會變動,請將根值設為包含具代表性物件紀錄的陣列,而非加入多個獨立的頂層值。
  2. 若有需要,輸入簡潔的 schema 標題。標題為選擇性項目。它可以讓複製的 schema 在版本控制或審閱時更容易辨識,但無法取代描述、業務名稱或其他書面化需求。
  3. 產生 schema。輸出會以 URI https://json-schema.org/draft/2020-12/schema 宣告 Draft 2020-12 dialect。解析與推論都在目前的分頁中進行,且邊界失敗不會產生部分 schema。
  4. 檢查物件結構。請確認巢狀物件具有 properties、每個屬性都依觀察到的型別推論出來,且只有在每個適用的物件中都被觀察到的屬性才會列在 required。屬性名稱會被完整保留,包括標點與 prototype 形式的拼寫。
  5. 檢視可空性與陣列。請留意與物件或項目型別並列加入的 null。對於非空陣列,請檢查推論出的 items 或 anyOf 分支。對於空陣列,預期會出現空白的 items schema,因為範例中沒有可以佐證的元素約束。
  6. 檢查開放物件決策。請確認 additionalProperties 不存在。這會允許額外的鍵,直到您的權威需求要求封閉物件為止;在這種情況下,schema 必須據此編輯。
  7. 將結果複製到您的 Python 工作流程中。將 schema 提供給應用程式已在使用的 Draft 2020-12 相容驗證器,然後使用其生產設定與詞彙測試正向與反向實例。

檢視推論出的結構

產生器會從範例進行確定性的觀察,但結果仍值得仔細閱讀。下表將 JSON 中的證據與可被支援的結構草稿分開呈現。

觀察到的範例證據Draft 2020-12 行為應檢閱項目
字串、布林值、null、安全整數或其他數字會發出對應的 JSON Schema 型別。請確認該值並非被當作識別符或精度敏感的十進位數使用,而應以字串表示與驗證。
相容的數字,例如 integer 與 numberInteger 會放寬為 number。請確認同時接受兩種數字形式符合應用程式契約。
不相容的觀察型別會以確定性的 anyOf 分支表示證據。請檢查分支順序,且只有在需求合理時才移除分支。
Null 與直接型別化的物件或項目結合會將 Null 加入 type 陣列,同時保留 properties 或 items。請驗證缺席確實是可空,而非另一種錯誤情境。
包含一個或多個觀察元素的陣列Items 會從每個觀察元素推論,包括混合證據。請測試每個觀察到的項目形狀以及這些形狀的組合。
空陣列會發出空白的 items schema。請依需求決定是否允許所有 JSON 項目型別,或 schema 需要更嚴格的 items 規則。
屬性至少在一個適用的物件中缺席不會列入 required。請勿將未列入 required 詮釋為對業務選填性的完整聲明。
只包含觀察到屬性的物件因為省略了 additionalProperties,物件會保持開放。只有當必須拒絕未見過的鍵時,才加入封閉物件政策。

巢狀物件與陣列會以遞迴方式推論,因此相同的決策可能出現在多個層級。重複且等價的分支會被移除,且輸出順序是確定性的。因此,使用相同的嚴格輸入會產生穩定的文字,可供審閱與提交,這也讓後續變更更容易檢視。

依據權威需求完成 Schema

產生的結構草稿刻意不會主張單一範例就能揭示所有語意規則。它不會推論 format、pattern、enum、const、minimum、maximum、multipleOf、長度限制、唯一性、描述、預設值、範例、棄用、readOnly、writeOnly、content encoding、參考、錨點、ID、條件邏輯、unevaluated properties 或業務意義。這些省略是刻意的限制:從拼字、標籤或少數範例加入精確約束,可能會產生比應用程式所能支援更嚴格的規則。

請依據文件、協定定義以及已在執行權威驗證的程式碼來檢視這些項目。舉例來說,某個字串可能看起來像電子郵件地址,但僅憑該觀察並不足以產生 format 約束。同樣地,包含一兩個類別值的範例不足以作為 enum 的證據。請只加入這些需求實際要求的約束。JSON Schema 2020-12 核心規格 提供了標準化詞彙,可在決定如何表達權威規則時參考。

Format 需要特別小心。Draft 2020-12 並不保證每個實作都會斷言 format 違規;行為可能取決於所選詞彙與驗證器設定。請確認生產環境中使用的確切實作與設定,而不是假設兩個程式庫提供相同的關鍵字行為。

在您的 Python 工作流程中測試複製的 Schema

將複製的 schema 傳遞給為 Python 專案所選的 Draft 2020-12 相容驗證器。產生器本身不是驗證器,因此在產生階段成功僅代表嚴格 JSON 已成功解析且產生了結構輸出。這並不能證明草稿符合您的應用程式規則,也未對任何實例執行 schema 測試。

請使用包含通過與拒絕文件的聚焦測試矩陣。您的矩陣應包含具代表性的結構、必填欄位省略、錯誤的基本型別、在不應為 null 的位置出現 null,以及無效的陣列項目。請新增對有效 anyOf 分支、無效 anyOf 分支,以及包含未觀察鍵之物件的檢查。對於巢狀結構,請在出現對應規則的每一層重複相同檢查。

驗證情境正向文件反向文件
必填欄位納入在每個適用物件中都被觀察到的欄位。省略列在 required 中的欄位。
可空性在產生的 type 陣列明確允許時使用 null。在結構為直接型別化且未包含 null 的情況下使用 null。
基本型別提供符合推論出的字串、整數、數字、布林值或 null 型別的值。在不接受的位置提供不同的 JSON 型別。
陣列項目提供符合推論 items schema 或觀察 anyOf 分支的項目。提供超出推論型別或分支的項目。
開放物件在範例尚未建立封閉物件政策時納入新的鍵。只有在權威需求加入該政策後,才拒絕未觀察到的鍵。

請使用與生產環境相同的驗證器、設定與詞彙執行最終檢查。僅憑 Draft 2020-12 標籤不足以保證實作行為一致。如果產生的草稿通過原始範例,卻無法表達書面化的規則,請依該需求編輯 schema,並重複執行完整的正向與反向測試集。

安全地處理無效或過大的樣本

必須使用嚴格 JSON。註解、結尾逗號、NaN、Infinity、undefined、BigInt 以及 JavaScript 字面值會直接失敗,而不是被默默修復。這在複製一份以 Python 為導向的草稿時特別重要:語法上方便的 Python 物件並不會自動變成嚴格 JSON。請先將預期的樣本轉換為嚴格 JSON,再交由產生器處理該值。

數值的處理同樣值得留意。JavaScript 會在推論前先解析樣本中的數字。只有安全整數會成為 JSON Schema 的整數;其他數字則會成為 number 值,以避免對較大的四捨五入數值做出錯誤的精確性宣稱。對於需要精度的十進位數或識別符,使用字串可能是較安全的做法,並以應用程式層級的驗證提供具權威性的規則。

產生器有其固定的邊界。它最多接受 500,000 個輸入字元、50,000 個值、40 層巢狀結構,以及 1,000,000 個輸出字元。超出邊界時不會產生部分綱要。若超過任一上限,請縮減樣本或簡化預期的輸出,千萬不要假設產生作業已以截斷的結果完成。

如需更深入的瞭解,請參閱 在瀏覽器中本地執行的 JSON 轉 CSV API 替代方案

如需更深入的瞭解,請參閱 在不上傳的情況下將 JSON 轉換為 Excel 表格