網際網路工程任務組 A. Wright,編輯
網際網路草案
預定狀態:資訊性 G. Luff
到期日:2017 年 10 月 23 日
H. Andrews,編輯
Cloudflare, Inc.
2017 年 4 月 21 日

JSON Schema 驗證:JSON 結構驗證的詞彙
draft-wright-json-schema-validation-01

摘要

JSON Schema (application/schema+json) 有多個用途,其中之一是 JSON 實例驗證。本文件指定 JSON Schema 的詞彙,用於描述 JSON 文件的含義、為使用 JSON 資料的使用者介面提供提示,並對有效文件的外觀作出斷言。

讀者注意事項

本草案的問題列表可以在 <https://github.com/json-schema-org/json-schema-spec/issues> 找到。

如需更多資訊,請參閱 <https://json-schema.dev.org.tw/>

如需提供回饋意見,請使用此問題追蹤器、首頁上列出的通訊方法,或以電子郵件聯絡文件編輯者。

本備忘錄的狀態

本網際網路草案的提交完全符合 BCP 78 和 BCP 79 的規定。

網際網路草案是網際網路工程任務組 (IETF) 的工作文件。請注意,其他群組也可能會將工作文件作為網際網路草案發布。目前網際網路草案的清單位於 http://datatracker.ietf.org/drafts/current/。

網際網路草案是有效期最長為六個月的草案文件,可能會隨時被其他文件更新、取代或廢止。將網際網路草案作為參考資料或以「工作中」之外的方式引用它們是不恰當的。

本網際網路草案將於 2017 年 10 月 23 日到期。

版權聲明

版權 (c) 2017 IETF Trust 以及被認定為文件作者的人員。保留所有權利。

本文件受 BCP 78 以及本文件發布之日生效的 IETF Trust 關於 IETF 文件的法律條款 (http://trustee.ietf.org/license-info) 約束。請仔細審閱這些文件,因為它們描述您對本文件的權利和限制。從本文件中提取的程式碼組件必須包含「簡化 BSD 授權」文字,如 Trust 法律條款第 4.e 節所述,並依「簡化 BSD 授權」所述提供,不提供任何擔保。


目錄

1. 簡介

JSON Schema 可用於要求指定的 JSON 文件(實例)滿足特定數量的條件。這些條件是透過使用本規範中描述的關鍵字來斷言。此外,還定義了一組關鍵字,以協助產生互動式使用者介面實例。

本規範將使用 JSON Schema 核心 [json-schema] 規範中定義的術語。

2. 慣例和術語

本文件中使用的關鍵字「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「MAY」和「OPTIONAL」應按照 RFC 2119 [RFC2119] 中的描述進行解釋。

本規範使用術語「容器實例」來表示陣列和物件實例。它使用術語「子實例」來表示陣列元素或物件成員值。

如果此陣列的任何兩個元素相等 [json-schema],則陣列值中的元素會被視為唯一。

3. 互通性考量

3.1. 字串實例的驗證

應注意,空字元 (\u0000) 在 JSON 字串中有效。要驗證的實例可能包含具有此字元的字串值,無論底層程式語言是否能夠處理此類資料。

3.2. 數值實例的驗證

JSON 規範允許具有任意精度的數字,而 JSON Schema 不會增加任何此類限制。這表示 JSON Schema 處理的數值實例可能任意大和/或具有任意長的十進位部分,無論底層程式語言是否能夠處理此類資料。

3.3. 正規表示式

兩個驗證關鍵字「pattern」和「patternProperties」使用正規表示式來表示約束。這些正規表示式應根據 ECMA 262 [ecma262] 正規表示式方言有效。

此外,鑑於正規表示式結構支援的差異很大,架構作者應將自己限制在以下正規表示式符號

最後,實作不得將正規表示式視為錨定的,無論是開頭或結尾。例如,這表示模式「es」會比對「expression」。

4. 一般驗證考量

4.1. 關鍵字和實例基本類型

大多數驗證關鍵字只會限制特定基本類型內的值。當實例的類型不是關鍵字目標的類型時,驗證會成功。

例如,「maxLength」關鍵字只會限制某些字串 (太長) 無效。如果實例是數字、布林值、空值、陣列或物件,則關鍵字會通過驗證。

4.2. 基本類型和子值的驗證

兩種基本類型 (陣列和物件) 允許有子值。基本類型的驗證會與子實例的驗證分開考量。

對於陣列,基本類型驗證包括使用「minItems」和「maxItems」驗證長度限制,而「items」和「additionalItems」會判斷哪些子架構適用於陣列的哪些元素。此外,「uniqueItems」和「contains」會驗證陣列的整體內容。

對於物件,基本類型驗證包括使用「required」、「minProperties」、「maxProperties」、「propertyNames」和「dependencies」的字串陣列形式驗證哪些屬性以及出現多少屬性的限制,而「properties」、「patternProperties」和「additionalProperties」會判斷哪些子架構適用於哪些物件屬性值。此外,「dependencies」的架構形式會根據特定屬性名稱是否存在來驗證物件的整體。

4.3. 約束和遺失的關鍵字

每個 JSON Schema 驗證關鍵字都會新增實例必須滿足才能成功驗證的約束。

遺失的驗證關鍵字永遠不會限制驗證。在某些情況下,此無作業行為與具有特定值的現有關鍵字相同,並且會在已知的情況下註記這些值。

4.4. 關鍵字的獨立性

驗證關鍵字通常會獨立運作,不會影響彼此的結果。

為了方便架構作者,有一些例外

5. 中繼架構

JSON Schema 驗證的目前 URI 是 <https://json-schema.dev.org.tw/draft-06/schema#>。

6. 驗證關鍵字

架構中的驗證關鍵字會對實例的成功驗證施加要求。

6.1. multipleOf

「multipleOf」的值必須是數字,且嚴格大於 0。

只有當除以此關鍵字的值會產生整數時,數值實例才有效。

6.2. maximum

「maximum」的值必須是數字,表示數值實例的包含上限。

如果實例是數字,則只有在實例小於或完全等於「maximum」時,此關鍵字才會驗證。

6.3. exclusiveMaximum

「exclusiveMaximum」的值必須是數字,表示數值實例的排除上限。

如果實例是一個數字,則該實例只有在值嚴格小於(不等於)"exclusiveMaximum" 時才有效。

6.4. minimum

"minimum" 的值必須是一個數字,表示數值實例的包含性上限。

如果實例是一個數字,則僅當該實例大於或等於 "minimum" 時,此關鍵字才會驗證為有效。

6.5. exclusiveMinimum

"exclusiveMinimum" 的值必須是一個數字,表示數值實例的排除性上限。

如果實例是一個數字,則該實例只有在值嚴格大於(不等於)"exclusiveMinimum" 時才有效。

6.6. maxLength

此關鍵字的值必須是一個非負整數。

如果字串實例的長度小於或等於此關鍵字的值,則該字串實例對於此關鍵字有效。

字串實例的長度定義為 RFC 7159 [RFC7159] 中定義的字元數。

6.7. minLength

此關鍵字的值必須是一個非負整數。

如果字串實例的長度大於或等於此關鍵字的值,則該字串實例對於此關鍵字有效。

字串實例的長度定義為 RFC 7159 [RFC7159] 中定義的字元數。

省略此關鍵字的行為與值為 0 的行為相同。

6.8. pattern

此關鍵字的值必須是一個字串。此字串應為有效的正規表達式,根據 ECMA 262 正規表達式方言。

如果正規表達式成功匹配該實例,則該字串實例被視為有效。請記住:正規表達式並非隱式錨定。

6.9. items

"items" 的值必須是有效的 JSON Schema 或有效的 JSON Schema 陣列。

此關鍵字決定了陣列的子實例如何驗證,而不會直接驗證直接實例本身。

如果 "items" 是一個 schema,如果陣列中的所有元素都成功地針對該 schema 進行驗證,則驗證成功。

如果 "items" 是一個 schema 陣列,如果實例的每個元素都針對相同位置的 schema 進行驗證(如果有的話),則驗證成功。

省略此關鍵字的行為與空 schema 的行為相同。

6.10. additionalItems

"additionalItems" 的值必須是一個有效的 JSON Schema。

此關鍵字決定了陣列的子實例如何驗證,而不會直接驗證直接實例本身。

如果 "items" 是一個 schema 陣列,如果每個位置大於 "items" 大小的實例元素都針對 "additionalItems" 進行驗證,則驗證成功。

否則,必須忽略 "additionalItems",因為 "items" schema(可能是空 schema 的預設值)會應用於所有元素。

省略此關鍵字的行為與空 schema 的行為相同。

6.11. maxItems

此關鍵字的值必須是一個非負整數。

如果陣列實例的大小小於或等於此關鍵字的值,則該陣列實例對於 "maxItems" 有效。

6.12. minItems

此關鍵字的值必須是一個非負整數。

如果陣列實例的大小大於或等於此關鍵字的值,則該陣列實例對於 "minItems" 有效。

省略此關鍵字的行為與值為 0 的行為相同。

6.13. uniqueItems

此關鍵字的值必須是一個布林值。

如果此關鍵字的布林值為 false,則實例成功通過驗證。如果其布林值為 true,則當其所有元素都是唯一時,實例成功通過驗證。

省略此關鍵字的行為與值為 false 的行為相同。

6.14. contains

此關鍵字的值必須是一個有效的 JSON Schema。

如果陣列實例的至少一個元素對給定的 schema 有效,則該陣列實例對於 "contains" 有效。

6.15. maxProperties

此關鍵字的值必須是一個非負整數。

如果物件實例的屬性數量小於或等於此關鍵字的值,則該物件實例對於 "maxProperties" 有效。

6.16. minProperties

此關鍵字的值必須是一個非負整數。

如果物件實例的屬性數量大於或等於此關鍵字的值,則該物件實例對於 "minProperties" 有效。

省略此關鍵字的行為與值為 0 的行為相同。

6.17. required

此關鍵字的值必須是一個陣列。此陣列的元素(如果有的話)必須是字串,並且必須是唯一的。

如果陣列中的每個項目都是實例中屬性的名稱,則該物件實例對於此關鍵字有效。

省略此關鍵字的行為與空陣列的行為相同。

6.18. properties

"properties" 的值必須是一個物件。此物件的每個值都必須是一個有效的 JSON Schema。

此關鍵字決定了物件的子實例如何驗證,而不會直接驗證直接實例本身。

如果對於實例中以及此關鍵字值內同時出現的每個名稱,該名稱的子實例都成功地針對相應的 schema 進行驗證,則驗證成功。

省略此關鍵字的行為與空物件的行為相同。

6.19. patternProperties

"patternProperties" 的值必須是一個物件。此物件的每個屬性名稱應為有效的正規表達式,根據 ECMA 262 正規表達式方言。此物件的每個屬性值都必須是一個有效的 JSON Schema。

此關鍵字決定了物件的子實例如何驗證,而不會直接驗證直接實例本身。針對此關鍵字的原始實例類型驗證始終成功。

如果對於每個與此關鍵字值中作為屬性名稱出現的任何正規表達式匹配的實例名稱,該名稱的子實例都成功地針對與匹配正規表達式對應的每個 schema 進行驗證,則驗證成功。

省略此關鍵字的行為與空物件的行為相同。

6.20. additionalProperties

"additionalProperties" 的值必須是一個有效的 JSON Schema。

此關鍵字決定了物件的子實例如何驗證,而不會直接驗證直接實例本身。

"additionalProperties" 的驗證僅適用於不匹配 "properties" 中任何名稱,且不匹配 "patternProperties" 中任何正規表達式的實例名稱的子值。

對於所有此類屬性,如果子實例針對 "additionalProperties" schema 進行驗證,則驗證成功。

省略此關鍵字的行為與空 schema 的行為相同。

6.21. dependencies

此關鍵字指定了當實例是一個物件並且包含特定屬性時所評估的規則。

此關鍵字的值必須是一個物件。每個屬性都指定一個相依性。每個相依性值必須是一個陣列或一個有效的 JSON Schema。

如果相依性值是一個子 schema,且相依性鍵是實例中的一個屬性,則整個實例必須針對相依性值進行驗證。

如果相依性值是一個陣列,則該陣列中的每個元素(如果有的話)必須是一個字串,並且必須是唯一的。如果相依性鍵是實例中的一個屬性,則相依性值中的每個項目都必須是實例中存在的屬性。

省略此關鍵字的行為與空物件的行為相同。

6.22. propertyNames

"propertyNames" 的值必須是一個有效的 JSON Schema。

如果實例是一個物件,則當實例中的每個屬性名稱都針對所提供的 schema 進行驗證時,此關鍵字將驗證為有效。請注意,schema 正在測試的屬性名稱始終是一個字串。

省略此關鍵字的行為與空 schema 的行為相同。

6.23. enum

此關鍵字的值必須是一個陣列。此陣列應至少有一個元素。陣列中的元素應是唯一的。

如果實例的值等於此關鍵字陣列值中的其中一個元素,則該實例成功通過此關鍵字的驗證。

陣列中的元素可以是任何值,包括 null。

6.24. const

此關鍵字的值可以是任何類型,包括 null。

如果實例的值等於此關鍵字的值,則該實例成功通過此關鍵字的驗證。

6.25. type

此關鍵字的值必須是一個字串或一個陣列。如果它是一個陣列,則陣列的元素必須是字串,並且必須是唯一的。

字串值必須是六種原始類型("null"、"boolean"、"object"、"array"、"number" 或 "string")之一,或是與任何小數部分為零的數字匹配的 "integer"。

只有當實例屬於此關鍵字列出的任何集合時,才會驗證為有效。

6.26. allOf

此關鍵字的值必須是一個非空陣列。陣列的每個項目都必須是一個有效的 JSON Schema。

如果實例成功地針對此關鍵字的值定義的所有 schema 進行驗證,則該實例成功地針對此關鍵字進行驗證。

6.27. anyOf

此關鍵字的值必須是一個非空陣列。陣列的每個項目都必須是一個有效的 JSON Schema。

如果實例成功地針對此關鍵字的值定義的至少一個 schema 進行驗證,則該實例成功地針對此關鍵字進行驗證。

6.28. oneOf

此關鍵字的值必須是一個非空陣列。陣列的每個項目都必須是一個有效的 JSON Schema。

如果實例成功地針對此關鍵字的值定義的恰好一個 schema 進行驗證,則該實例成功地針對此關鍵字進行驗證。

6.29. not

此關鍵字的值必須是一個有效的 JSON Schema。

如果實例未能成功地針對此關鍵字定義的 schema 進行驗證,則該實例對於此關鍵字有效。

7. 元數據關鍵字

7.1. definitions

此關鍵字的值必須是一個物件。此物件的每個成員值都必須是一個有效的 JSON Schema。

此關鍵字本身在驗證中不起作用。它的作用是為 schema 作者提供一個標準化的位置,以便將 JSON Schema 內嵌到更通用的 schema 中。

{
    "type": "array",
    "items": { "$ref": "#/definitions/positiveInteger" },
    "definitions": {
        "positiveInteger": {
            "type": "integer",
            "exclusiveMinimum": 0
        }
    }
}

                        

例如,以下是一個描述正整數陣列的 schema,其中正整數約束是 "definitions" 中的子 schema

7.2. "title" 和 "description"

這兩個關鍵字的值都必須是一個字串。

這兩個關鍵字都可用於裝飾使用者介面,提供有關此使用者介面產生的資料的資訊。標題最好簡短,而描述將提供關於此 schema 所描述的實例用途的解釋。

7.3. "default"

此關鍵字的值沒有任何限制。

此關鍵字可用於提供與特定 schema 關聯的預設 JSON 值。建議預設值對於相關 schema 有效。

7.4. "examples"

此關鍵字的值必須是一個陣列。陣列中的值沒有任何限制。

此關鍵字可用於提供與特定 schema 關聯的範例 JSON 值,以說明用法。建議這些值對於相關 schema 有效。

如果存在,則實作可以將 "default" 的值用作附加範例。如果沒有 "examples",則仍然可以以這種方式使用 "default"。

8. 使用「format」進行語意驗證

8.1. 前言

單獨的結構驗證可能不足以驗證實例是否滿足應用程式的所有要求。「format」關鍵字旨在針對由權威資源(無論是 RFC 或其他外部規範)準確描述的固定值子集,提供可互通的語意驗證。

此關鍵字的值稱為格式屬性。它必須是一個字串。格式屬性通常只能驗證給定的一組實例類型。如果要驗證的實例類型不在這個集合中,則對於此格式屬性和實例的驗證應該成功。

8.2. 實作要求

實作可以支援「format」關鍵字。如果它們選擇這樣做

實作可以添加自訂格式屬性。除非各方之間達成協議,否則綱要作者不應期望同級實作支援此關鍵字和/或自訂格式屬性。

8.3. 定義的格式

8.3.1. date-time

此屬性適用於字串實例。

如果字串實例是有效的日期表示法,如 RFC 3339, section 5.6 [RFC3339] 所定義,則此字串實例對此屬性有效。

8.3.2. email

此屬性適用於字串實例。

如果字串實例是有效的網際網路電子郵件地址,如 RFC 5322, section 3.4.1 [RFC5322] 所定義,則此字串實例對此屬性有效。

8.3.3. hostname

此屬性適用於字串實例。

如果字串實例是網際網路主機名稱的有效表示法,如 RFC 1034, section 3.1 [RFC1034] 所定義,則此字串實例對此屬性有效。

8.3.4. ipv4

此屬性適用於字串實例。

如果字串實例是根據 RFC 2673, section 3.2 [RFC2673] 中定義的「點分四組」ABNF 語法有效的 IPv4 位址表示法,則此字串實例對此屬性有效。

8.3.5. ipv6

此屬性適用於字串實例。

如果字串實例是有效的 IPv6 位址表示法,如 RFC 2373, section 2.2 [RFC2373] 所定義,則此字串實例對此屬性有效。

8.3.6. uri

此屬性適用於字串實例。

如果字串實例是有效的 URI,根據 [RFC3986] 所定義,則此字串實例對此屬性有效。

8.3.7. uri-reference

此屬性適用於字串實例。

如果字串實例是有效的 URI 參考(URI 或相對參考),根據 [RFC3986] 所定義,則此字串實例對此屬性有效。

8.3.8. uri-template

此屬性適用於字串實例。

如果字串實例是有效的 URI 範本(任何級別),根據 [RFC6570] 所定義,則此字串實例對此屬性有效。

8.3.9. json-pointer

此屬性適用於字串實例。

如果字串實例是有效的 JSON 指標,根據 [RFC6901] 所定義,則此字串實例對此屬性有效。

9. 安全考量

JSON Schema 驗證定義了 JSON Schema 核心的詞彙表,並涉及其中列出的所有安全考量。

JSON Schema 驗證允許使用正規表示式,正規表示式有許多不同的(通常不相容的)實作。某些實作允許嵌入任意程式碼,這超出 JSON Schema 的範圍,絕對不應允許。正規表示式通常也可以設計成計算成本極高(所謂的「災難性回溯」),導致阻斷服務攻擊。

10. 參考文獻

10.1. 規範性參考文獻

, "
[RFC2119] Bradner, S., RFC 中用於表示需求等級的關鍵字", BCP 14, RFC 2119, DOI 10.17487/RFC2119, 1997 年 3 月。
[json-schema]JSON Schema:用於描述 JSON 文件的媒體類型", Internet-Draft draft-wright-json-schema-00, 2016 年 10 月。

10.2. 資訊性參考文獻

, "
[RFC1034] Mockapetris, P., "網域名稱 - 概念與設施", STD 13, RFC 1034, DOI 10.17487/RFC1034, 1987 年 11 月。
[RFC2373] Hinden, R.S. Deering, "IP 第 6 版定址架構", RFC 2373, DOI 10.17487/RFC2373, 1998 年 7 月。
[RFC2673] Crawford, M., "網域名稱系統中的二進位標籤", RFC 2673, DOI 10.17487/RFC2673, 1999 年 8 月。
[RFC3339] Klyne, G.C. Newman, "網際網路上的日期和時間:時間戳記", RFC 3339, DOI 10.17487/RFC3339, 2002 年 7 月。
[RFC3986] Berners-Lee, T., Fielding, R.L. Masinter, "統一資源識別碼 (URI):通用語法", STD 66, RFC 3986, DOI 10.17487/RFC3986, 2005 年 1 月。
[RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M.D. Orchard, "URI 範本", RFC 6570, DOI 10.17487/RFC6570, 2012 年 3 月。
[RFC6901] Bryan, P., Zyp, K.M. Nottingham, "JavaScript 物件標記法 (JSON) 指標", RFC 6901, DOI 10.17487/RFC6901, 2013 年 4 月。
[RFC7159] Bray, T., "JavaScript 物件標記法 (JSON) 資料交換格式", RFC 7159, DOI 10.17487/RFC7159, 2014 年 3 月。
[RFC5322] Resnick, P., 網際網路訊息格式", RFC 5322, DOI 10.17487/RFC5322, 2008 年 10 月。
[ecma262]ECMA 262 規範"

附錄 A. 致謝

感謝 Gary Court、Francis Galiegue、Kris Zyp 和 Geraint Luff 為 JSON Schema 的初始草案所做的貢獻。

感謝 Jason Desrosiers、Daniel Perrett、Erik Wilde、Ben Hutton、Evgeny Poberezkin、Brad Bowman、Gowry Sankar、Donald Pipowitch 和 Dave Finlay 為文件所做的提交和修補。

附錄 B. 變更記錄

[CREF1]本節將在離開 Internet-Draft 狀態之前刪除。

draft-wright-json-schema-validation-01

draft-wright-json-schema-validation-00

draft-fge-json-schema-validation-01

作者地址

Austin Wright (編輯) 電子郵件: [email protected]
Geraint Luff 電子郵件: [email protected]
Henry Andrews (編輯) Cloudflare, Inc. 電子郵件: [email protected]