網際網路工程任務組 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 授權」文字,如「信託法律條款」第 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」關鍵字僅會限制某些字串 (過長的字串) 無效。如果實例是數字、布林值、Null、陣列或物件,則關鍵字會通過驗證。

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 綱要驗證的目前 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 綱要或有效的 JSON 綱要陣列。

這個關鍵字決定了子執行個體如何驗證陣列,並且不直接驗證直接執行個體本身。

如果「items」是一個綱要,則如果陣列中的所有元素都成功對該綱要進行驗證,則驗證成功。

如果「items」是一個綱要陣列,則如果執行個體的每個元素都對相同位置的綱要(如果有的話)進行驗證,則驗證成功。

省略這個關鍵字的效果與空綱要相同。

6.10. additionalItems

「additionalItems」的值必須是有效的 JSON 綱要。

這個關鍵字決定了子執行個體如何驗證陣列,並且不直接驗證直接執行個體本身。

如果「items」是一個綱要陣列,則如果每個位置大於「items」大小的執行個體元素都對「additionalItems」進行驗證,則驗證成功。

否則,必須忽略「additionalItems」,因為「items」綱要(可能是空綱要的預設值)會套用於所有元素。

省略這個關鍵字的效果與空綱要相同。

6.11. maxItems

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

如果陣列執行個體的大小小於或等於這個關鍵字的值,則該陣列執行個體對「maxItems」有效。

6.12. minItems

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

如果陣列執行個體的大小大於或等於這個關鍵字的值,則該陣列執行個體對「minItems」有效。

省略這個關鍵字的效果與值為 0 相同。

6.13. uniqueItems

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

如果這個關鍵字的值為布林值 false,則執行個體驗證成功。如果它的值為布林值 true,則如果它的所有元素都是唯一的,執行個體會驗證成功。

省略這個關鍵字的效果與值為 false 相同。

6.14. contains

這個關鍵字的值必須是有效的 JSON 綱要。

如果陣列執行個體的至少一個元素對給定的綱要有效,則該陣列執行個體對「contains」有效。

6.15. maxProperties

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

如果物件執行個體的屬性數小於或等於這個關鍵字的值,則該物件執行個體對「maxProperties」有效。

6.16. minProperties

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

如果物件執行個體的屬性數大於或等於這個關鍵字的值,則該物件執行個體對「minProperties」有效。

省略這個關鍵字的效果與值為 0 相同。

6.17. required

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

如果陣列中的每個項目都是執行個體中的屬性名稱,則物件執行個體對這個關鍵字有效。

省略這個關鍵字的效果與空陣列相同。

6.18. properties

「properties」的值必須是一個物件。這個物件的每個值必須是一個有效的 JSON 綱要。

這個關鍵字決定了子執行個體如何驗證物件,並且不直接驗證直接執行個體本身。

如果每個同時出現在執行個體和這個關鍵字值中的名稱,其對應的子執行個體都成功對應到綱要驗證,則驗證成功。

省略這個關鍵字的效果與空物件相同。

6.19. patternProperties

「patternProperties」的值必須是一個物件。這個物件的每個屬性名稱應該是一個有效的正規表示式,根據 ECMA 262 正規表示式方言。這個物件的每個屬性值必須是一個有效的 JSON 綱要。

這個關鍵字決定了子執行個體如何驗證物件,並且不直接驗證直接執行個體本身。針對這個關鍵字的原始執行個體類型驗證永遠會成功。

如果每個符合此關鍵字的值中作為屬性名稱出現的任何正規表示式的執行個體名稱,其子執行個體都成功針對每個對應到符合的正規表示式的綱要進行驗證,則驗證成功。

省略這個關鍵字的效果與空物件相同。

6.20. additionalProperties

「additionalProperties」的值必須是有效的 JSON 綱要。

這個關鍵字決定了子執行個體如何驗證物件,並且不直接驗證直接執行個體本身。

使用「additionalProperties」進行驗證僅適用於不符合「properties」中任何名稱的執行個體名稱的子值,並且不符合「patternProperties」中的任何正規表示式。

對於所有這些屬性,如果子執行個體對「additionalProperties」綱要進行驗證,則驗證成功。

省略這個關鍵字的效果與空綱要相同。

6.21. dependencies

這個關鍵字指定了當執行個體是一個物件並且包含某個屬性時要評估的規則。

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

如果相依性值是一個子綱要,且相依性鍵是執行個體中的屬性,則整個執行個體必須對相依性值進行驗證。

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

省略這個關鍵字的效果與空物件相同。

6.22. propertyNames

「propertyNames」的值必須是有效的 JSON 綱要。

如果執行個體是一個物件,則如果執行個體中的每個屬性名稱都對所提供的綱要進行驗證,則這個關鍵字會驗證成功。請注意,綱要測試的屬性名稱將始終是一個字串。

省略這個關鍵字的效果與空綱要相同。

6.23. enum

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

如果執行個體的值等於這個關鍵字的陣列值中的一個元素,則執行個體對這個關鍵字會驗證成功。

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

6.24. const

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

如果執行個體的值等於關鍵字的值,則執行個體對這個關鍵字會驗證成功。

6.25. type

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

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

如果執行個體位於為這個關鍵字列出的任何集合中,則執行個體會進行驗證。

6.26. allOf

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

如果執行個體對這個關鍵字的值定義的所有綱要都成功驗證,則該執行個體對這個關鍵字會驗證成功。

6.27. anyOf

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

如果執行個體對這個關鍵字的值定義的至少一個綱要都成功驗證,則該執行個體對這個關鍵字會驗證成功。

6.28. oneOf

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

如果執行個體對這個關鍵字的值定義的正好一個綱要成功驗證,則該執行個體對這個關鍵字會驗證成功。

6.29. not

這個關鍵字的值必須是一個有效的 JSON 綱要。

如果執行個體未能對這個關鍵字定義的綱要成功進行驗證,則該執行個體對這個關鍵字有效。

7. 中繼資料關鍵字

7.1. definitions

這個關鍵字的值必須是一個物件。這個物件的每個成員值必須是一個有效的 JSON 綱要。

這個關鍵字本身不參與驗證。它的作用是為綱要作者提供一個標準化的位置,將 JSON 綱要內聯到更通用的綱要中。

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

                        

例如,這是一個描述正整數陣列的綱要,其中正整數限制是「definitions」中的子綱要

7.2. 「title」和「description」

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

這兩個關鍵字都可用於使用有關此使用者介面產生的資料的資訊來裝飾使用者介面。標題最好簡短,而說明將提供關於此綱要描述的執行個體用途的說明。

7.3. 「default」

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

這個關鍵字可用於提供與特定綱要關聯的預設 JSON 值。建議預設值應符合相關的綱要。

7.4. 「examples」

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

這個關鍵字可用於提供與特定綱要關聯的範例 JSON 值,以說明用法。建議這些值應符合相關的綱要。

實作可以將「default」的值(如果存在)用作額外的範例。如果缺少「examples」,仍然可以使用「default」。

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

8.1. 前言

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

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

8.2. 實作要求

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

實作可以新增自訂的格式屬性。除了各方之間的協議外,綱要作者不應期望對等實作支援此關鍵字和/或自訂格式屬性。

8.3. 定義的格式

8.3.1. date-time

此屬性適用於字串實例。

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

8.3.2. email

此屬性適用於字串實例。

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

8.3.3. hostname

此屬性適用於字串實例。

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

8.3.4. ipv4

此屬性適用於字串實例。

如果字串實例是 RFC 2673 第 3.2 節 [RFC2673] 定義的「點分四組」ABNF 語法所描述的有效 IPv4 位址表示形式,則此字串實例對此屬性有效。

8.3.5. ipv6

此屬性適用於字串實例。

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

8.3.6. uri

此屬性適用於字串實例。

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

8.3.7. uri-reference

此屬性適用於字串實例。

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

8.3.8. uri-template

此屬性適用於字串實例。

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

8.3.9. json-pointer

此屬性適用於字串實例。

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

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 文件的媒體類型」,網際網路草案 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]此部分將在離開網際網路草案狀態之前移除。

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]