網際網路草案 JSON Schema 驗證 2022 年 6 月
Wright 等人 於 2022 年 12 月 18 日到期 [頁]
工作小組
網際網路工程任務組
網際網路草案
draft-bhutton-json-schema-validation-01
發佈日期
預定狀態
資訊性
到期日
作者
A. Wright, 編輯
H. Andrews, 編輯
B. Hutton, 編輯
Postman

JSON Schema 驗證:JSON 結構驗證的詞彙

摘要

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) 的工作文件。請注意,其他群組也可能將工作文件作為網際網路草案發佈。目前網際網路草案的清單位於 https://datatracker.ietf.org/drafts/current/

網際網路草案是有效期最長為六個月的草稿文件,並可能隨時被其他文件更新、取代或廢棄。不宜將網際網路草案作為參考資料,或在引用時僅以「工作進行中」的形式引用。

本網際網路草案將於 2022 年 12 月 18 日到期。

目錄

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. 概述

JSON Schema 驗證會對實例資料的結構斷言約束。然後,滿足所有斷言約束的實例位置會使用任何包含非斷言資訊(例如描述性元資料和使用提示)的關鍵字進行註解。如果實例中的所有位置都滿足所有斷言約束,則稱該實例對架構有效。

每個架構物件都會針對其適用的每個實例位置進行獨立評估。這透過確保驗證器不需要在整個文件驗證過程中維護狀態,大大簡化了驗證器的實作需求。

本規範定義了一組斷言關鍵字,以及一個小的元資料關鍵字詞彙,可用於使用有用的資訊註解 JSON 實例。第 7 節的關鍵字主要用作註解,但也可以選擇用作斷言。第 8 節的關鍵字是處理嵌入為 JSON 字串的文件的註解。

4. 互通性考量

4.1. 字串實例的驗證

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

4.2. 數值實例的驗證

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

4.3. 正規表示式

使用正規表示式,或將實例值限制為正規表示式的關鍵字,須遵守 JSON Schema Core [json-schema] 規格中關於正規表示式的互通性考量。

5. 後設綱要

預設 JSON Schema 方言後設綱要的目前 URI 是 https://json-schema.dev.org.tw/draft/2020-12/schema。為了方便綱要作者,此後設綱要描述了一種方言,該方言包含本規格和 JSON Schema Core 規格中定義的所有詞彙,以及兩個保留用於過渡期的前關鍵字。下方每個章節都提供了個別詞彙和詞彙後設綱要 URI。某些詞彙是選擇性支援的,這會在相關章節中詳細說明。

為了更正錯誤,詞彙和後設綱要 URI 的更新版本可能會在規格草案之間發布。實作應將本規格草案之後和下一個草案之前的日期所列出的 URI 視為表示與此處所列出的語法和語意相同。

6. 用於結構驗證的詞彙

綱要中的驗證關鍵字對實例的成功驗證施加了要求。這些關鍵字都是斷言,沒有任何註釋行為。

不使用 "$vocabulary" 的後設綱要應被視為要求此詞彙,如同其 URI 存在且值為 true。

此詞彙(稱為「驗證」詞彙)的目前 URI 為:<https://json-schema.dev.org.tw/draft/2020-12/vocab/validation>。

對應後設綱要的目前 URI 為:https://json-schema.dev.org.tw/draft/2020-12/meta/validation

6.1. 任何實例類型的驗證關鍵字

6.1.1. type

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

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

如果 "type" 的值是字串,則如果實例的類型與字串值所表示的類型相符,則實例會成功驗證。如果 "type" 的值是陣列,則如果實例的類型與陣列中字串所指示的任何類型相符,則實例會成功驗證。

6.1.2. enum

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

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

陣列中的元素可能是任何類型,包括 null。

6.1.3. const

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

使用此關鍵字的功能等同於具有單一值的 "enum" (第 6.1.2 節)

如果實例的值等於關鍵字的值,則實例會針對此關鍵字成功驗證。

6.2. 數值實例(number 和 integer)的驗證關鍵字

6.2.1. multipleOf

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

只有當數值實例除以此關鍵字的值時結果為整數時,該數值實例才有效。

6.2.2. maximum

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

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

6.2.3. exclusiveMaximum

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

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

6.2.4. minimum

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

如果實例是數字,則只有當實例大於或完全等於 "minimum" 時,此關鍵字才會驗證。

6.2.5. exclusiveMinimum

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

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

6.3. 字串的驗證關鍵字

6.3.1. maxLength

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

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

字串實例的長度定義為 RFC 8259 [RFC8259] 所定義的字元數。

6.3.2. minLength

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

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

字串實例的長度定義為 RFC 8259 [RFC8259] 所定義的字元數。

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

6.3.3. pattern

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

如果正規表示式成功符合實例,則字串實例會被視為有效。回想一下:正規表示式不會隱式錨定。

6.4. 陣列的驗證關鍵字

6.4.1. maxItems

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

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

6.4.2. minItems

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

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

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

6.4.3. uniqueItems

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

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

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

6.4.4. maxContains

此關鍵字的值必須為非負整數。

如果相同的綱要物件中不存在 "contains",則此關鍵字無效。

實例陣列針對 "maxContains" 的驗證方式有兩種,取決於相鄰的 "contains" [json-schema] 關鍵字的註解結果形式。第一種方式是如果註解結果是陣列,且該陣列的長度小於或等於 "maxContains" 的值。第二種方式是如果註解結果是布林值 "true",且實例陣列的長度小於或等於 "maxContains" 的值。

6.4.5. minContains

此關鍵字的值必須為非負整數。

如果相同的綱要物件中不存在 "contains",則此關鍵字無效。

實例陣列針對 "minContains" 的驗證方式有兩種,取決於相鄰的 "contains" [json-schema] 關鍵字的註解結果形式。第一種方式是如果註解結果是陣列,且該陣列的長度大於或等於 "minContains" 的值。第二種方式是如果註解結果是布林值 "true",且實例陣列的長度大於或等於 "minContains" 的值。

允許值為 0,但僅適用於設定從 0 到 "maxContains" 值的出現次數範圍。值為 0 會使 "minContains" 和 "contains" 始終通過驗證 (但驗證仍可能因為 "maxContains" 關鍵字而失敗)。

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

6.5. 物件的驗證關鍵字

6.5.1. maxProperties

此關鍵字的值必須為非負整數。

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

6.5.2. minProperties

此關鍵字的值必須為非負整數。

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

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

6.5.3. required

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

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

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

6.5.4. dependentRequired

此關鍵字的值必須為物件。此物件中的屬性(如果有的話)必須是陣列。每個陣列中的元素(如果有的話)必須是字串,並且必須是唯一的。

此關鍵字指定如果存在特定其他屬性時所要求的屬性。它們的要求取決於其他屬性的存在。

如果實例和此關鍵字值的名稱中都出現的每個名稱,其對應陣列中的每個項目也是實例中屬性的名稱,則驗證成功。

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

7. 具有 "format" 的語意內容詞彙表

7.1. 前言

單獨的結構驗證可能不足以讓應用程式正確使用某些值。定義 "format" 註解關鍵字是為了讓綱要作者能夠傳達語意資訊,這些語意資訊適用於可由權威資源(無論是 RFC 或其他外部規範)準確描述的固定子集值。

此關鍵字的值稱為格式屬性。它必須是字串。格式屬性通常只能驗證給定的實例類型集。如果要驗證的實例類型不在這個集合中,則此格式屬性和實例的驗證應該成功。本節中定義的所有格式屬性都適用於字串,但可以指定格式屬性適用於在 核心 JSON 綱要 [json-schema] 中定義的資料模型中定義的任何實例類型。 請注意,本規範中的 "type" 關鍵字定義了不屬於資料模型的 "integer" 類型。因此,格式屬性可以限制為數字,但不能特別限制為整數。但是,數字格式可以與值為 "integer" 的 "type" 關鍵字一起使用,或者可以明確定義為如果數字不是整數則始終通過,這產生的行為與僅應用於整數基本相同。

此詞彙表的目前 URI(稱為格式註解詞彙表)是:<https://json-schema.dev.org.tw/draft/2020-12/vocab/format-annotation>。對應的後設綱要的目前 URI 是:https://json-schema.dev.org.tw/draft/2020-12/meta/format-annotation。必須實作此詞彙表的支援。

除了格式註解詞彙表外,還有一個次要詞彙表可用於自訂後設綱要,該綱要將 "format" 定義為斷言。格式斷言詞彙表的 URI 為:<https://json-schema.dev.org.tw/draft/2020-12/vocab/format-assertion>。對應的後設綱要的目前 URI 是:https://json-schema.dev.org.tw/draft/2020-12/meta/format-assertion。實作格式斷言詞彙表的支援是可選的。

由於格式斷言詞彙表的要求是格式註解詞彙表的超集,因此同時指定格式註解和格式斷言詞彙表在功能上等同於僅指定格式斷言詞彙表。

7.2. 實作要求

"format" 關鍵字的功能由引用的詞彙表定義。

7.2.1. 格式註解詞彙表

如果實作支援註解收集,則必須將格式的值作為註解收集。這可在綱要驗證不可用或不足時啟用應用程式層級驗證。

除了註解之外,實作也可以將 "format" 視為斷言,並嘗試驗證該值是否符合指定的語意。實作必須提供選項來啟用和停用此類評估,並且預設情況下必須停用。實作應記錄其對此類驗證的支援程度。 指定格式註解詞彙表並在實作中啟用驗證不應視為等同於指定格式斷言詞彙表,因為當未指定格式斷言詞彙表時,不要求實作提供完整的驗證支援。

當實作設定為斷言行為時,它:

  • 應為以下定義的每個格式屬性提供實作特定的盡力驗證;
  • 可以選擇將任何或所有格式屬性的驗證實作為無操作,方法是始終產生 true 的驗證結果;

這符合實作的目前情況,針對某些或所有格式屬性,實作提供的驗證程度差異很大,包括根本沒有驗證。它也旨在鼓勵僅依賴註解行為,並在應用程式中執行語意驗證,這是建議的最佳做法。

7.2.2. 格式斷言詞彙表

當使用值 true 宣告格式斷言詞彙表時,實作必須為本規範定義的所有格式提供完整的驗證支援。無法提供完整驗證支援的實作必須拒絕處理綱要。

支援格式斷言詞彙表的實作:

  • 如果實作支援註解收集,則仍然必須將 "format" 作為註解收集;
  • 必須將 "format" 評估為斷言;
  • 必須為本規範中定義的所有格式屬性以及其識別的任何其他格式屬性實作語法驗證,以便存在正確類型的可能實例值,這些值將會驗證失敗。

由於許多屬性中涉及的複雜性,因此對格式屬性的最低驗證要求有意模糊且寬鬆。請特別注意,該要求僅限於語法檢查;不應期望實作會傳送電子郵件、嘗試連線到 URL,或以其他方式檢查由格式實例識別的實體是否存在。 預期對於 date-time 等簡單格式,語法驗證將會很徹底。對於電子郵件地址等複雜格式,它們是各種標準和時間上的眾多調整的組合,其中包含可能會或可能不會受到使用該值的其他應用程式限制的模糊和/或過時規則,因此最少的驗證就已足夠。例如,不包含 "@" 的實例字串顯然不是有效的電子郵件地址,而包含 7 位元 ASCII 以外字元的 "email" 或 "hostname" 也顯然無效。

建議實作為每個格式使用通用剖析程式庫或知名的正規表示式。實作應清楚記錄如何以及在多大程度上驗證每個格式屬性。

標準核心和驗證後設綱要 (第 5 節) 的 "$vocabulary" 關鍵字的值包含此詞彙表(值為 false),因為預設情況下不要求實作支援此關鍵字作為斷言。已知支援格式詞彙表(值為 true)會大幅增加程式碼大小,在某些情況下還會增加執行時間,而且並不適用於所有實作。

7.2.3. 自訂格式屬性

實作可以支援自訂格式屬性。除非各方達成協議,否則綱要作者不應期望對等實作支援此類自訂格式屬性。實作不得因未知格式而無法收集為註解。當指定格式斷言詞彙時,實作遇到未知格式時必須失敗。

詞彙不支援明確宣告關鍵字的不同值集合。由於此限制,以及此關鍵字歷史上不均勻的實作,如果需要互操作性,建議在自訂詞彙中定義額外的關鍵字,而不是額外的格式屬性。

7.3. 定義的格式

7.3.1. 日期、時間和持續時間

這些屬性適用於字串實例。

日期和時間格式名稱源自 RFC 3339,第 5.6 節 [RFC3339]。持續時間格式來自 RFC 3339 附錄 A 中給出的 ISO 8601 ABNF。

支援格式的實作應實作對以下屬性的支援:

date-time
如果字串實例根據「date-time」ABNF 規則(如上所述)是有效的表示,則該實例對此屬性有效。
date
如果字串實例根據「full-date」ABNF 規則(如上所述)是有效的表示,則該實例對此屬性有效。
time
如果字串實例根據「full-time」ABNF 規則(如上所述)是有效的表示,則該實例對此屬性有效。
duration
如果字串實例根據「duration」ABNF 規則(如上所述)是有效的表示,則該實例對此屬性有效。

實作可以使用該 RFC 中定義的其他格式名稱支援其他屬性。如果實作了「full-date」或「full-time」,則必須實作相應的簡短形式(分別為「date」或「time」),並且行為必須相同。除非根據該格式的規則進行驗證,否則實作不應使用任何與 RFC 3339 格式匹配的名稱來定義擴展屬性。 目前對於支援所有 RFC 3339 格式的需求尚未達成共識,因此這種保留命名空間的方法將鼓勵實驗,而不會承諾使用整個集合。格式實作需求通常會變得更加靈活,或者這些可能會被提升為完全指定的屬性或被刪除。

7.3.2. 電子郵件地址

這些屬性適用於字串實例。

如果字串實例是有效的網際網路電子郵件地址,則該實例對這些屬性有效,如下所示:

email
RFC 5321 第 4.1.2 節 [RFC5321] 中的「Mailbox」ABNF 規則定義。
idn-email
RFC 6531 第 3.3 節 [RFC6531] 中的擴展「Mailbox」ABNF 規則定義。

請注意,所有對「email」屬性有效的字串也對「idn-email」屬性有效。

7.3.3. 主機名稱

這些屬性適用於字串實例。

如果字串實例是網際網路主機名稱的有效表示,則該實例對這些屬性有效,如下所示:

hostname
RFC 1123 第 2.1 節 [RFC1123] 定義,包括使用 RFC 5891 第 4.4 節 [RFC5891] 中指定的 Punycode 演算法產生之主機名稱。
idn-hostname
由 RFC 1123 (如同 hostname) 定義,或由 RFC 5890 第 2.3.2.3 節 [RFC5890] 定義的國際化主機名稱。

請注意,所有對「hostname」屬性有效的字串也對「idn-hostname」屬性有效。

7.3.4. IP 位址

這些屬性適用於字串實例。

如果字串實例是 IP 位址的有效表示,則該實例對這些屬性有效,如下所示:

ipv4
根據 RFC 2673 第 3.2 節 [RFC2673] 中定義的「dotted-quad」ABNF 語法之 IPv4 位址。
ipv6
RFC 4291 第 2.2 節 [RFC4291] 定義的 IPv6 位址。

7.3.5. 資源識別符

這些屬性適用於字串實例。

uri
如果字串實例是有效的 URI,根據 [RFC3986],則該實例對此屬性有效。
uri-reference
如果字串實例是有效的 URI 參考(URI 或相對參考),根據 [RFC3986],則該實例對此屬性有效。
iri
如果字串實例是有效的 IRI,根據 [RFC3987],則該實例對此屬性有效。
iri-reference
如果字串實例是有效的 IRI 參考(IRI 或相對參考),根據 [RFC3987],則該實例對此屬性有效。
uuid
如果字串實例是有效的 UUID 字串表示形式,根據 [RFC4122],則該實例對此屬性有效。

請注意,所有有效的 URI 都是有效的 IRI,並且所有有效的 URI 參考也是有效的 IRI 參考。

另請注意,「uuid」格式適用於純 UUID,而不是 URN 中的 UUID。一個範例是「f81d4fae-7dec-11d0-a765-00a0c91e6bf6」。對於作為 URN 的 UUID,請使用「uri」格式,並使用「^urn:uuid:」的「pattern」正規表示式來表示 URI 方案和 URN 命名空間。

7.3.6. uri-template

此屬性適用於字串實例。

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

請注意,URI 範本可以用於 IRI;沒有單獨的 IRI 範本規範。

7.3.7. JSON 指標

這些屬性適用於字串實例。

json-pointer
如果字串實例是 JSON 指標的有效 JSON 字串表示形式,根據 RFC 6901 第 5 節 [RFC6901],則該實例對此屬性有效。
relative-json-pointer
如果字串實例是有效的 相對 JSON 指標 [相對 JSON 指標],則該實例對此屬性有效。

為了允許絕對和相對 JSON 指標,請使用「anyOf」或「oneOf」來指示對任一格式的支援。

7.3.8. regex

此屬性適用於字串實例。

一個正規表示式,應根據 ECMA-262 [ecma262] 正規表示式方言有效。

驗證格式的實作必須至少接受此規格的 正規表示式 (第 4.3 節) 節中定義的 ECMA-262 子集,並且應接受所有有效的 ECMA-262 表示式。

8. 字串編碼資料內容的詞彙

8.1. 前言

本節中定義的註解表示實例包含以 JSON 字串編碼的非 JSON 資料。

這些屬性提供將 JSON 資料解譯為豐富多媒體文件所需的其他資訊。它們描述內容類型、其編碼方式和/或如何驗證。它們不作為驗證斷言;格式不正確的字串編碼文件不得導致包含實例被視為無效。

不使用「$vocabulary」的中繼綱要應被視為要求此詞彙,就像它的 URI 以 true 值存在一樣。

此詞彙 (稱為內容詞彙) 的目前 URI 為:<https://json-schema.dev.org.tw/draft/2020-12/vocab/content>。

對應的元模式目前的 URI 為:https://json-schema.dev.org.tw/draft/2020-12/meta/content

8.2. 實作要求

由於安全性和效能的考量,以及可能內容類型的開放式本質,實作**不得**預設自動解碼、剖析和/或驗證字串內容。這也額外支援嵌入式文件的使用案例,這些文件旨在由處理包含文件的消費者以外的其他消費者處理。

本節中的所有關鍵字僅適用於字串,對其他資料類型沒有影響。

實作**可以**提供自動解碼、剖析和/或驗證字串內容的能力。但是,**不得**預設執行這些操作,並且**必須**將每個字串編碼文件的驗證結果與封閉的文件分開提供。此過程**應該**等同於根據原始模式完整評估實例,然後使用註釋來解碼、剖析和/或驗證每個字串編碼的文件。目前,對於執行和回傳這種自動解碼、剖析和驗證功能的已剖析資料和/或驗證結果的確切機制,尚未明確指定。如果此功能證明受歡迎,可能會在未來的草案中更詳盡地指定。

另請參閱安全考量第 10 節章節,了解根據這些關鍵字自動處理實例字串可能引入的漏洞。

8.3. contentEncoding

如果實例值為字串,則此屬性定義該字串**應該**被解釋為編碼的二進位資料,並使用此屬性命名的編碼進行解碼。

RFC 4648 [RFC4648] 中列出了指示 base 16、32 和 64 編碼及其幾種變體的可能值。此外,RFC 2045 [RFC2045] 的 6.7 和 6.8 節提供了 MIME 中使用的編碼。此關鍵字源自 MIME 的 Content-Transfer-Encoding 標頭,該標頭旨在將二進位資料對應到 ASCII 字元。它與 HTTP 的 Content-Encoding 標頭無關,後者用於編碼(例如,壓縮或加密)HTTP 請求和回應的內容。

由於 RFC 中都定義了「base64」,因此**應該**假設使用 RFC 4648 中的定義,除非該字串明確指定用於 MIME 環境中。請注意,所有這些編碼都會產生僅由 7 位元 ASCII 字元組成的字串。因此,此關鍵字對於包含該範圍之外的字元的字串沒有任何意義。

如果此關鍵字不存在,但存在「contentMediaType」,則表示編碼是身分編碼,這表示為了將內容表示為 UTF-8 字串,不需要進行任何轉換。

此屬性的值**必須**為字串。

8.4. contentMediaType

如果實例為字串,則此屬性表示該字串內容的媒體類型。如果存在「contentEncoding」,則此屬性描述解碼後的字串。

此屬性的值**必須**為字串,且**必須**是 RFC 2046 [RFC2046] 中定義的媒體類型。

8.5. contentSchema

如果實例為字串,且存在「contentMediaType」,則此屬性包含一個描述字串結構的模式。

此關鍵字**可以**與任何可以對應到 JSON Schema 資料模型的媒體類型一起使用。

此屬性的值**必須**是有效的 JSON 模式。如果不存在「contentMediaType」,則**應該**忽略它。

8.6. 範例

以下是一個範例模式,說明了「contentEncoding」和「contentMediaType」的使用:

{
    "type": "string",
    "contentEncoding": "base64",
    "contentMediaType": "image/png"
}

此模式描述的實例預期為字串,並且其值應可解釋為 base64 編碼的 PNG 圖像。

另一個範例:

{
    "type": "string",
    "contentMediaType": "text/html"
}

此模式描述的實例預期為包含 HTML 的字串,使用將 JSON 字串解碼成的任何字元集。根據 RFC 8259 [RFC8259] 的 8.1 節,在完全封閉的系統之外,這**必須**是 UTF-8。

此範例描述了一個使用 HMAC SHA-256 演算法進行 MAC 簽章的 JWT,並且在其聲明集中需要「iss」和「exp」欄位。

{
    "type": "string",
    "contentMediaType": "application/jwt",
    "contentSchema": {
        "type": "array",
        "minItems": 2,
        "prefixItems": [
            {
                "const": {
                    "typ": "JWT",
                    "alg": "HS256"
                }
            },
            {
                "type": "object",
                "required": ["iss", "exp"],
                "properties": {
                    "iss": {"type": "string"},
                    "exp": {"type": "integer"}
                }
            }
        ]
    }
}

請注意,「contentEncoding」並未出現。雖然「application/jwt」媒體類型使用 base64url 編碼,但這是由媒體類型定義的,它決定了如何將 JWT 字串解碼為兩個 JSON 資料結構的清單:首先是標頭,然後是有效負載。由於 JWT 媒體類型確保 JWT 可以用 JSON 字串表示,因此無需進一步編碼或解碼。

9. 基本中繼資料註解的詞彙

這些通用註解關鍵字提供常用於文件和使用者介面顯示的資訊。它們並非旨在形成一套完整的功能集。相反,可以為更複雜的基於註解的應用程式定義其他詞彙。

不使用「$vocabulary」的元模式**應該**被視為要求此詞彙,如同其 URI 出現且值為 true 一樣。

此詞彙(稱為中繼資料詞彙)目前的 URI 為:<https://json-schema.dev.org.tw/draft/2020-12/vocab/meta-data>。

對應的元模式目前的 URI 為:https://json-schema.dev.org.tw/draft/2020-12/meta/meta-data

9.1. 「title」和「description」

這兩個關鍵字的值**必須**為字串。

這兩個關鍵字都可以用來以有關此使用者介面產生的資料資訊裝飾使用者介面。「title」最好簡短,而「description」將提供有關此模式描述的實例用途的說明。

9.2. 「default」

此關鍵字的值沒有任何限制。當此關鍵字的多個出現適用於單個子實例時,實作**應該**移除重複項。

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

9.3. 「deprecated」

此關鍵字的值**必須**為布林值。當此關鍵字的多個出現適用於單個子實例時,如果任何出現指定為 true 值,應用程式**應該**將實例位置視為已棄用。

如果「deprecated」的值為布林值 true,則表示應用程式**應該**避免使用宣告的屬性。這可能表示該屬性將在未來被移除。

包含「deprecated」且值為 true 的根模式表示所描述的整個資源**可能**在未來被移除。

「deprecated」關鍵字適用於包含該關鍵字的模式物件成功套用的每個實例位置。這可能會導致每個陣列項目或物件屬性都被棄用的情況,即使包含的陣列或物件未被棄用。

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

9.4. 「readOnly」和「writeOnly」

這些關鍵字的值**必須**為布林值。當這些關鍵字的多個出現適用於單個子實例時,如果任何出現指定為 true 值,則產生的行為**應該**與 true 值相同,否則**應該**與 false 值相同。

如果「readOnly」的值為布林值 true,則表示實例的值完全由擁有權限的機構管理,並且應用程式嘗試修改此屬性值的行為預計將被該擁有權限的機構忽略或拒絕。

如果整個文件都被標記為「readOnly」,則該實例文件在傳送到擁有權限的機構時,**可能**會被忽略,或者**可能**會導致錯誤,由該機構自行決定。

如果「writeOnly」的值為布林值 true,則表示當從擁有權限的機構檢索實例時,該值永遠不會出現。它可以在傳送到擁有權限的機構以更新或建立文件(或其代表的資源)時出現,但它不會包含在任何更新或新建立的實例版本中。

如果整個文件都被標記為「writeOnly」,則該實例文件在檢索時**可能**會以某種形式的空白文件回傳,或者**可能**會在檢索時產生錯誤,或者讓檢索請求被忽略,由該機構自行決定。

例如,「readOnly」將用於將資料庫產生的序號標記為唯讀,而「writeOnly」將用於標記密碼輸入欄位。

這些關鍵字可用於協助產生使用者介面實例。特別是,應用程式**可以**選擇對唯寫欄位使用在輸入時隱藏輸入值的 Widget。

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

9.5. 「examples」

此關鍵字的值**必須**為陣列。陣列中的值沒有任何限制。當此關鍵字的多個出現適用於單個子實例時,實作**必須**提供所有值的扁平陣列,而不是陣列的陣列。

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

如果存在,實作**可以**使用「default」的值作為額外的範例。如果不存在「examples」,仍然**可以**以此方式使用「default」。

10. 安全考量

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

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

支援根據 "contentEncoding" 和/或 "contentMediaType" 驗證或評估實例字串資料的實作方式,有可能因為誤導性資訊而以不安全的方式評估資料。應用程式可以透過僅在建立 schema 和實例之間的關係時(例如,它們共享相同的授權)執行此類處理來減輕這種風險。

處理媒體類型或編碼時,需考慮該媒體類型或編碼的安全考量。例如,當處理 JSON 字串內編碼的 JavaScript 或 ECMAScript 時,RFC 4329 Scripting Media Types [RFC4329] 的安全考量適用。

11. 參考文獻

11.1. 規範性參考文獻

[RFC2119]
Bradner, S., "在 RFC 中用於表示需求等級的關鍵字", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>
[RFC1123]
Braden, R., Ed., "網際網路主機的需求 - 應用程式和支援", STD 3, RFC 1123, DOI 10.17487/RFC1123, , <https://www.rfc-editor.org/info/rfc1123>
[RFC2045]
Freed, N.N. Borenstein, "多用途網際網路郵件擴充(MIME)第一部分:網際網路訊息主體格式", RFC 2045, DOI 10.17487/RFC2045, , <https://www.rfc-editor.org/info/rfc2045>
[RFC2046]
Freed, N.N. Borenstein, "多用途網際網路郵件擴充(MIME)第二部分:媒體類型", RFC 2046, DOI 10.17487/RFC2046, , <https://www.rfc-editor.org/info/rfc2046>
[RFC2673]
Crawford, M., "網域名稱系統中的二進位標籤", RFC 2673, DOI 10.17487/RFC2673, , <https://www.rfc-editor.org/info/rfc2673>
[RFC3339]
Klyne, G.C. Newman, "網際網路上的日期和時間:時間戳記", RFC 3339, DOI 10.17487/RFC3339, , <https://www.rfc-editor.org/info/rfc3339>
[RFC3986]
Berners-Lee, T., Fielding, R., 和 L. Masinter, "統一資源識別碼(URI):通用語法", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>
[RFC3987]
Duerst, M.M. Suignard, "國際化資源識別碼(IRI)", RFC 3987, DOI 10.17487/RFC3987, , <https://www.rfc-editor.org/info/rfc3987>
[RFC4122]
Leach, P., Mealling, M., 和 R. Salz, "通用唯一識別碼(UUID)URN 命名空間", RFC 4122, DOI 10.17487/RFC4122, , <https://www.rfc-editor.org/info/rfc4122>
[RFC4291]
Hinden, R.S. Deering, "IP 版本 6 定址架構", RFC 4291, DOI 10.17487/RFC4291, , <https://www.rfc-editor.org/info/rfc4291>
[RFC4648]
Josefsson, S., "Base16、Base32 和 Base64 資料編碼", RFC 4648, DOI 10.17487/RFC4648, , <https://www.rfc-editor.org/info/rfc4648>
[RFC5321]
Klensin, J., "簡易郵件傳輸協定", RFC 5321, DOI 10.17487/RFC5321, , <https://www.rfc-editor.org/info/rfc5321>
[RFC5890]
Klensin, J., "應用程式國際化網域名稱(IDNA):定義和文件框架", RFC 5890, DOI 10.17487/RFC5890, , <https://www.rfc-editor.org/info/rfc5890>
[RFC5891]
Klensin, J., "應用程式國際化網域名稱(IDNA):協定", RFC 5891, DOI 10.17487/RFC5891, , <https://www.rfc-editor.org/info/rfc5891>
[RFC6570]
Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., 和 D. Orchard, "URI 範本", RFC 6570, DOI 10.17487/RFC6570, , <https://www.rfc-editor.org/info/rfc6570>
[RFC6531]
Yao, J.W. Mao, "國際化電子郵件的 SMTP 擴充", RFC 6531, DOI 10.17487/RFC6531, , <https://www.rfc-editor.org/info/rfc6531>
[RFC6901]
Bryan, P., Ed., Zyp, K., 和 M. Nottingham, Ed., "JavaScript 物件表示法(JSON)指標", RFC 6901, DOI 10.17487/RFC6901, , <https://www.rfc-editor.org/info/rfc6901>
[RFC8259]
Bray, T., Ed., "JavaScript 物件表示法(JSON)資料交換格式", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/info/rfc8259>
[ecma262]
"ECMA-262,第 11 版規範", , <https://262.ecma-international.org/5.1/>
[relative-json-pointer]
Luff, G., Andrews, H., 和 B. Hutton, Ed., "相對 JSON 指標", 工作中, Internet-Draft, draft-handrews-relative-json-pointer-01, , <https://datatracker.ietf.org/doc/html/draft-handrews-relative-json-pointer-01>
[json-schema]
Wright, A., Andrews, H., Hutton, B., 和 G. Dennis, "JSON Schema:用於描述 JSON 文件的媒體類型", 工作中, Internet-Draft, draft-bhutton-json-schema-01, , <https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-01>

11.2. 參考性參考文獻

[RFC4329]
Hoehrmann, B., "腳本媒體類型", RFC 4329, DOI 10.17487/RFC4329, , <https://www.rfc-editor.org/info/rfc4329>

附錄 A. 從驗證移至核心的關鍵字

從此草案起,有幾個關鍵字已從本文檔移至 核心規範 [json-schema],在某些情況下進行了重新命名或其他變更。這會影響以下先前的驗證關鍵字:

"definitions"
重新命名為 "$defs",以符合 "$ref" 並縮短輸入長度。Schema 字彙作者不應定義具有不同行為的 "definitions" 關鍵字,以避免使仍然使用舊名稱的 schema 失效。雖然此文件引用的單一字彙 meta-schema 中不存在 "definitions",但它仍然存在於預設 meta-schema 中,並且在使用了該 meta-schema 時,實作應假設 "$defs" 和 "definitions" 具有相同的行為。
"allOf"、"anyOf"、"oneOf"、"not"、"if"、"then"、"else"、"items"、"additionalItems"、"contains"、"propertyNames"、"properties"、"patternProperties"、"additionalProperties"
所有這些關鍵字都將子 schema 應用於實例並組合其結果,而不聲明自己的任何條件。如果沒有斷言關鍵字,這些應用程式只能透過使用 false 布林值 schema 或反轉 true 布林值 schema(或等效 schema 物件)的結果來導致斷言失敗。因此,它們最好被定義為一個通用機制,驗證、超 schema 和擴充字彙都可以基於此機制。
"dependencies"
這個關鍵字有兩種不同的行為模式,這使得其實作和推論相對困難。Schema 形式已移至核心並重新命名為 "dependentSchemas",作為應用程式字彙的一部分。它類似於 "properties",不同之處在於它不是將其子 schema 應用於屬性值,而是將其應用於包含該屬性的物件。屬性名稱陣列形式保留在此處並重新命名為 "dependentRequired",因為它是一個斷言,它是 "required" 斷言關鍵字條件使用的快捷方式。

附錄 B. 致謝

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

感謝 Jason Desrosiers、Daniel Perrett、Erik Wilde、Evgeny Poberezkin、Brad Bowman、Gowry Sankar、Donald Pipowitch、Dave Finlay、Denis Laxalde、Phil Sturgeon、Shawn Silverman 和 Karen Etheridge 為本文檔提交的內容和補丁。

附錄 C. 變更記錄

本節在離開 Internet-Draft 狀態之前將被移除。

draft-bhutton-json-schema-validation-01
  • 改進並澄清 "minContains" 關鍵字的說明
  • 移除使用 "production",改用 "ABNF 規則"
draft-bhutton-json-schema-validation-00
  • 將電子郵件格式 RFC 參考修正為 5321 而不是 5322
  • 澄清 "contentEncoding" 值的集合和含義
  • 參考 ECMA-262,第 11 版以取得正規表示式支援
  • 將 "format" 分割成僅限註解的詞彙表和斷言詞彙表
  • 當 "deprecated" 適用於陣列時,澄清其意義
draft-handrews-json-schema-validation-02
  • 將關鍵字分組為正式的詞彙表
  • 根據詞彙表更新 "format" 的實作要求
  • 預設情況下,"format" 不得進行驗證,儘管可以啟用驗證
  • 詞彙表宣告可用於要求 "format" 驗證
  • 將 "definitions" 作為 "$defs" 移動到核心規範中
  • 將應用程式關鍵字移動到核心規範中
  • 將 "dependencies" 的陣列形式重新命名為 "dependentRequired",並將 schema 形式移動到核心規範中
  • 將所有 "content*" 關鍵字指定為註解,而非斷言
  • 新增 "contentSchema" 以允許將 schema 應用於字串編碼的文件
  • 也允許在 "contentEncoding" 中使用 RFC 4648 編碼
  • 新增 "minContains" 和 "maxContains"
  • 更新 "hostname" 和 "idn-hostname" 的 RFC 參考
  • 新增 "uuid" 和 "duration" 格式
draft-handrews-json-schema-validation-01
  • 此草案純粹是澄清,沒有功能上的變更
  • 提供在 "not" 和類似情況下忽略註解的普遍原則
  • 澄清 "if"/"then"/"else" 驗證互動
  • 澄清 "if"/"then"/"else" 對於註解的行為
  • 微小的格式和交叉參考改進
draft-handrews-json-schema-validation-00
  • 新增 "if"/"then"/"else"
  • 根據核心規範將關鍵字分類為斷言或註解
  • 警告未來可能會移除 "dependencies"
  • 將驗證關鍵字分組到子章節中,以提高可讀性
  • 將 "readOnly" 從超架構移動到驗證元數據
  • 新增 "writeOnly"
  • 新增字串編碼的媒體章節,包含先前的超架構 "media" 關鍵字
  • 恢復 "regex" 格式(移除是無意的)
  • 新增 "date" 和 "time" 格式,並保留其他 RFC 3339 格式名稱
  • I18N 格式:"iri"、"iri-reference"、"idn-hostname"、"idn-email"
  • 澄清 "json-pointer" 格式表示字串編碼,而非 URI 片段
  • 修正了使 "minimum" 和 "exclusiveMinimum" 含義反轉的錯字
  • 將格式語法參考移動到規範性參考文獻中
  • JSON 是一種規範性要求
draft-wright-json-schema-validation-01
  • 標準化使用帶完整單字的連字號格式名稱("uriref" 變成 "uri-reference")
  • 新增格式 "uri-template" 和 "json-pointer"
  • 將 "exclusiveMaximum"/"exclusiveMinimum" 從 "maximum"/"minimum" 的布林修飾符更改為獨立的數字欄位。
  • 將 additionalItems/items 分割為兩個部分
  • 重新設計 properties/patternProperties/additionalProperties 的定義
  • 新增 "examples" 關鍵字
  • 新增 "contains" 關鍵字
  • 允許空的 "required" 和 "dependencies" 陣列
  • 修正了對原始類型的 "type" 參考
  • 新增 "const" 關鍵字
  • 新增 "propertyNames" 關鍵字
draft-wright-json-schema-validation-00
  • 新增其他安全考量
  • 移除對「最新版本」元架構的參考,改為使用編號版本
  • 為了簡潔起見,重新措辭了許多關鍵字的定義
  • 新增也允許相對 URI 參考的 "uriref" 格式
draft-fge-json-schema-validation-00
  • 初始草案。
  • 從草案 v3 中拯救出來。
  • 重新定義 "required" 關鍵字。
  • 移除 "extends"、"disallow"
  • 新增 "anyOf"、"allOf"、"oneOf"、"not"、"definitions"、"minProperties"、"maxProperties"。
  • "dependencies" 成員值不能再是單一字串;屬性依賴陣列中至少需要一個元素。
  • 將 "divisibleBy" 重新命名為 "multipleOf"。
  • "type" 陣列不能再有 schema;移除 "any" 作為可能的值。
  • 重新設計 "format" 章節;使支援成為可選。
  • "format":移除屬性 "phone"、"style"、"color";將 "ip-address" 重新命名為 "ipv4";為所有屬性新增參考。
  • 提供計算陣列/物件實例的 schema 的演算法。
  • 新增互操作性考量。

作者地址

Austin Wright (編輯)
Henry Andrews (編輯)
Ben Hutton (編輯)
Postman