idnits 2.17.1 draft-json-schema-language-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The abstract seems to contain references ([RFC8259]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == The document seems to lack the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. (The document does seem to have the reference to RFC 2119 which the ID-Checklist requires). -- The document date (June 06, 2019) is 1786 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 585 -- Looks like a reference, but probably isn't: '2' on line 585 -- Looks like a reference, but probably isn't: '3' on line 585 Summary: 1 error (**), 0 flaws (~~), 2 warnings (==), 4 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 JSON Working Group U. Carion 3 Internet-Draft June 06, 2019 4 Intended status: Standards Track 5 Expires: December 8, 2019 7 JSON Schema Language 8 draft-json-schema-language-01 10 Abstract 12 JavaScript Object Notation (JSON) Schema Language is a portable 13 method for describing the format of JSON ([RFC8259], JavaScript 14 Object Notation) data and the errors associated with ill-formed data. 16 Status of This Memo 18 This Internet-Draft is submitted in full conformance with the 19 provisions of BCP 78 and BCP 79. 21 Internet-Drafts are working documents of the Internet Engineering 22 Task Force (IETF). Note that other groups may also distribute 23 working documents as Internet-Drafts. The list of current Internet- 24 Drafts is at https://datatracker.ietf.org/drafts/current/. 26 Internet-Drafts are draft documents valid for a maximum of six months 27 and may be updated, replaced, or obsoleted by other documents at any 28 time. It is inappropriate to use Internet-Drafts as reference 29 material or to cite them other than as "work in progress." 31 This Internet-Draft will expire on December 8, 2019. 33 Copyright Notice 35 Copyright (c) 2019 IETF Trust and the persons identified as the 36 document authors. All rights reserved. 38 This document is subject to BCP 78 and the IETF Trust's Legal 39 Provisions Relating to IETF Documents 40 (https://trustee.ietf.org/license-info) in effect on the date of 41 publication of this document. Please review these documents 42 carefully, as they describe your rights and restrictions with respect 43 to this document. Code Components extracted from this document must 44 include Simplified BSD License text as described in Section 4.e of 45 the Trust Legal Provisions and are provided without warranty as 46 described in the Simplified BSD License. 48 Table of Contents 50 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 51 1.1. Requirements notation . . . . . . . . . . . . . . . . . . 3 52 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 3 53 2. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 54 3. Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . 8 55 3.1. Strict instance semantics . . . . . . . . . . . . . . . . 9 56 3.2. Errors . . . . . . . . . . . . . . . . . . . . . . . . . 9 57 3.3. Forms . . . . . . . . . . . . . . . . . . . . . . . . . . 10 58 3.3.1. Empty . . . . . . . . . . . . . . . . . . . . . . . . 10 59 3.3.2. Ref . . . . . . . . . . . . . . . . . . . . . . . . . 10 60 3.3.3. Type . . . . . . . . . . . . . . . . . . . . . . . . 11 61 3.3.4. Enum . . . . . . . . . . . . . . . . . . . . . . . . 12 62 3.3.5. Elements . . . . . . . . . . . . . . . . . . . . . . 12 63 3.3.6. Properties . . . . . . . . . . . . . . . . . . . . . 13 64 3.3.7. Values . . . . . . . . . . . . . . . . . . . . . . . 16 65 3.3.8. Discriminator . . . . . . . . . . . . . . . . . . . . 16 66 4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 20 67 5. Security Considerations . . . . . . . . . . . . . . . . . . . 20 68 6. Normative References . . . . . . . . . . . . . . . . . . . . 20 69 Appendix A. Comparison with CDDL . . . . . . . . . . . . . . . . 21 70 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 24 71 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 24 73 1. Introduction 75 This document describes a schema language for JSON [RFC8259] called 76 JSON Schema Language (JSL). 78 The goals of JSL are to: 80 o Provide an unambiguous description of the overall structure of a 81 JSON document. 83 o Be able to describe common JSON datatypes and structures. 85 o Provide a single format that is readable and editable by both 86 humans and machines, and which can be embedded within other JSON 87 documents. 89 o Enable code generation from schemas. 91 o Provide a standardized format for errors when data does not 92 conform with a schema. 94 JSL is intentionally designed as a rather minimal schema language. 95 For example, JSL is homoiconic (it both describes, and is written in, 96 JSON) yet is incapable of describing in detail its own structure. By 97 keeping the expressiveness of the schema language minimal, JSL makes 98 code generation and standardized errors easier to implement. 100 It is expected that for many use-cases, a schema language of JSL's 101 expressiveness is sufficient. Where a more expressive language is 102 required, alternatives exist in CDDL and others. 104 This document has the following structure: 106 The syntax of JSL is defined in Section 2. Section 3 describes the 107 semantics of JSL; this includes determining whether some data 108 satisfies a schema and what errors should be produced when the data 109 is unsatisfactory. Appendix A presents various JSL schemas and their 110 CDDL equivalents. 112 1.1. Requirements notation 114 The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, 115 SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this 116 document, are to be interpreted as described in [RFC2119] [RFC8174]. 118 1.2. Terminology 120 The terms "absolute-URI" and "URI-reference", when they appear in 121 this document, are to be understood as they are defined in [RFC3986]. 123 The term "JSON Pointer", when it appears in this document, is to be 124 understood as it is defined in [RFC6901]. 126 The term "instance", when it appears in this document, refers to a 127 JSON value being validated against a JSL schema. 129 2. Syntax 131 This section describes when a JSON document is a correct JSL schema. 133 A correct JSL schema MUST match the "schema" CDDL rule described in 134 this section. A JSL schema is a JSON object taking on an appropriate 135 form. It may optionally contain definitions (a mapping from names to 136 schemas) and additional data. 138 schema = { 139 form, 140 ? definitions: { * tstr => schema } 141 } 142 This is not a correct JSL schema, as its "definitions" object 143 contains a number, which is not a schema: 145 { "definitions": { "foo": 3 }} 147 JSL schemas can take on one of eight forms. These forms are defined 148 so as to be mutually exclusive; a schema cannot satisfy multiple 149 forms at once. 151 form = empty / 152 ref / 153 type / 154 enum / 155 elements / 156 properties / 157 values / 158 discriminator 160 The first form, "empty", is trivial. It is meant for matching any 161 instance: 163 empty = {} 165 Thus, this is a correct schema: 167 {} 169 The second form, "ref", is for when a schema is meant to be defined 170 in terms of something in "definitions": 172 ref = { ref: tstr } 174 In a correct schema, the "ref" value must always refer to a 175 definition at the root level of a schema. Note well: the _root_ 176 level of the schema. Definitions at the non-root level are 177 immaterial. More formally: 179 Let _D_ be the member of the root schema with the name "definitions". 180 For all schemas _S_ of the ref form in the root schema, let _R_ be 181 the value of the member of _S_ with the name "ref". In a correct 182 schema, _D_ MUST exist and MUST have a member with a name equal to 183 _R_. 185 Here is an example of ref's use to avoid re-defining the same thing 186 twice: 188 { 189 "definitions": { 190 "coordinates": { 191 "properties": { 192 "lat": { "type": "number" }, 193 "lng": { "type": "number" } 194 } 195 } 196 }, 197 "properties": { 198 "user_location": { "ref": "coordinates" }, 199 "server_location": { "ref": "coordinates" } 200 } 201 } 203 However, this schema is incorrect, as it refers to a definition that 204 doesn't exist: 206 { 207 "definitions": { "foo": { "type": "number" }}, 208 "ref": "bar" 209 } 211 This schema is incorrect as well, as it refers to a definition that 212 doesn't exist at the root level. The non-root definition is 213 immaterial: 215 { 216 "definitions": { "foo": { "type": "number" }}, 217 "elements": { 218 "definitions": { "bar": { "type": "number" }}, 219 "ref": "bar" 220 } 221 } 223 The third form, "type", constrains instances to have a particular 224 primitive type. The precise meaning of each of the primitive types 225 is described in Section 3. 227 type = { type: "boolean" / "number" / "string" / "timestamp" } 229 For example, this schema constrains instances to be strings that are 230 correct [RFC3339] timestamps: 232 { "type": "timestamp" } 234 The fourth form, "enum", describes instances whose value must be one 235 of a finite, predetermined set of values: 237 enum = { enum: [+ tstr] } 239 The values within "[+ tstr]" MUST NOT contain duplicates. Thus, the 240 following is a correct schema: 242 { "enum": ["IN_PROGRESS", "DONE", "CANCELED"] } 244 But this is not a correct schema, as "B" is duplicated: 246 { "enum": ["A", "B", "B"] } 248 The fifth form, "elements", describes instances that must be arrays. 249 A further sub-schema describes the elements of the array. 251 elements = { elements: schema } 253 Here is a schema describing an array of [RFC3339] timestamps: 255 { "elements": { "type": "timestamp" }} 257 The sixth form, "properties", describes JSON objects being used as a 258 "struct". A schema of this form specifies the names of required and 259 optional properties, as well as the schemas each of those properties 260 must satisfy: 262 ; One of properties or optionalProperties may be omitted, 263 ; but not both. 264 properties = with-properties / with-optional-properties 266 with-properties = { 267 properties: * tstr => schema, 268 ? optionalProperties * tstr => schema 269 } 271 with-optional-properties = { 272 ? properties: * tstr => schema, 273 optionalProperties: * tstr => schema 274 } 276 If a schema has both a member named "properties" (with value _P_) and 277 another member named "optionalProperties" (with value _O_), then _O_ 278 and _P_ MUST NOT have any member names in common. This is to prevent 279 ambiguity as to whether a property is optional or required. 281 Thus, this is not a correct schema, as "confusing" appears in both 282 "properties" and "optionalProperties": 284 { 285 "properties": { "confusing": {} }, 286 "optionalProperties": { "confusing": {} } 287 } 289 Here is a correct schema, describing a paginated list of users: 291 { 292 "properties": { 293 "users": { 294 "elements": { 295 "properties": { 296 "id": { "type": "string" }, 297 "name": { "type": "string" }, 298 "create_time": { "type": "timestamp" } 299 }, 300 "optionalProperties": { 301 "delete_time": { "type": "timestamp" } 302 } 303 } 304 }, 305 "next_page_token": { "type": "string" } 306 } 307 } 309 The seventh form, "values", describes JSON objects being used as an 310 associative array. A schema of this form specifies the form all 311 member values must satisfy, but places no constraints on the member 312 names: 314 values = { values: * tstr => schema } 316 Thus, this is a correct schema, describing a mapping from strings to 317 numbers: 319 { "values": { "type": "number" }} 321 Finally, the eighth form, "discriminator", describes JSON objects 322 being used as a discriminated union. A schema of this form specifies 323 the "tag" (or "discriminator") of the union, as well as a mapping 324 from tag values to the appropriate schema to use. 326 ; Note well: the values of mapping are of the properties form. 327 discriminator = { tag: tstr, mapping: * tstr => properties } 329 To prevent ambiguous or unsatisfiable contstraints on the "tag" of a 330 discriminator, an additional constraint on the discriminator form 331 exists: 333 Let _T_ be the value of the member with the name "tag", and let _M_ 334 be the value of the member with the name "mapping". Then for all 335 values _S_ of the members of _M_, _S_ must not contain members named 336 "properties" or "optionalProperties" whose values contain members 337 with a name equal to _T_. 339 Thus, this is an incorrect schema, as "event_type" is both the value 340 of "tag" and a member name in one of the mapping member "properties": 342 { 343 "tag": "event_type", 344 "mapping": { 345 "is_event_type_a_string_or_a_number?": { 346 "properties": { "event_type": { "type": "number" }} 347 } 348 } 349 } 351 However, this is a correct schema, describing a pattern of data 352 common in JSON-based messaging systems: 354 { 355 "tag": "event_type", 356 "mapping": { 357 "account_deleted": { 358 "properties": { 359 "account_id": { "type": "string" } 360 } 361 }, 362 "account_payment_plan_changed": { 363 "properties": { 364 "account_id": { "type": "string" }, 365 "payment_plan": { "enum": ["FREE", "PAID"] } 366 }, 367 "optionalProperties": { 368 "upgraded_by": { "type": "string" } 369 } 370 } 371 } 372 } 374 3. Semantics 376 This section describes when an instance is valid against a correct 377 JSL schema, and the standardized errors to produce when an instance 378 is invalid. 380 3.1. Strict instance semantics 382 Users will have different desired behavior with respect to 383 "unspcecified" members in an instance. For example: 385 { "properties": { "a": { "type": "string" }}} 387 Some users may expect that "{"a": "foo", "b": "bar"}" satisfies the 388 above schema. Others may disagree. JSL addresses this point of 389 contention by leaving it to implementations whether to accept such 390 "unspecified" members, or whether to reject them. 392 Rejecting "unspecified" members is called "strict instance 393 semantics". Whether to use strict instance semantics is not 394 specified within a schema - it is considered out-of-band information. 396 Implementations MAY allow users to choose whether to use strict 397 instance semantics. Implementations SHOULD document whether they use 398 strict instance semantics by default. 400 See Section 3.3.6 for how strict instance semantics affects schema 401 evaluation. 403 3.2. Errors 405 To facilitate consistent validation error handling, this document 406 specifies a standard error format. Implementations SHOULD support 407 producing errors in this standard form. 409 The standard error format is a JSON array. The order of the elements 410 of this array is not specified. The elements of this array are JSON 411 objects with two members: 413 o A member with the name "instancePath", whose value is a JSON 414 string encoding a JSON Pointer. This JSON Pointer will point to 415 the part of the instance that was rejected. 417 o A member with the name "schemaPath", whose value is a JSON string 418 encoding a JSON Pointer. This JSON Pointer will point to the part 419 of the schema that rejected the instance. 421 The values for "instancePath" and "schemaPath" depend on the form of 422 the schema, and are described in detail in Section 3.3. 424 3.3. Forms 426 This section describes, for each of the eight JSL schema forms, the 427 rules dictating whether an instance is accepted, as well as the 428 standardized errors to produce when an instance is invalid. 430 The forms a correct schema may take on are formally described in 431 Section 2. 433 3.3.1. Empty 435 The empty form is meant to describe instances whose values are 436 unknown, unpredictable, or otherwise unconstrained by the schema. 438 If a schema is of the empty form, then it accepts all instances. An 439 empty schema will never produce any errors. 441 3.3.2. Ref 443 The ref form is for when a schema is meant to be defined in terms of 444 something in the "definitions" of the root schema. The ref form 445 enables schemas to be less repetitive, and also enables describing 446 recursive structures. 448 If a schema is of the ref form, then: 450 o Let _B_ be the root schema containing the schema. 452 o Let _D_ be the member of _B_ with the name "definitions". By 453 Section 2, _D_ exists. 455 o Let _R_ be the value of the schema member with the name "ref". 457 o Let _S_ be the value of the member of _D_ whose name equals _R_. 458 By Section 2, _S_ exists, and is a schema. 460 The schema accepts the instance if and only if _S_ accepts the 461 instance. Otherwise, the standard errors to return in this case are 462 the union of the errors from evaluating _S_ against the instance. 464 For example, the schema: 466 { 467 "definitions": { "a": { "type": "number" }}, 468 "ref": "a" 469 } 470 Accepts 123 but not false. The standard errors to produce when 471 evaluting false against this schema are: 473 [{ "instancePath": "", "schemaPath": "/definitions/a/type" }] 475 Note that the ref form is defined to only look up definitions at the 476 root level. Thus, with the schema: 478 { 479 "definitions": { "a": { "type": "number" }}, 480 "elements": { 481 "definitions": { "a": { "type": "boolean" }}, 482 "ref": "foo" 483 } 484 } 486 The instance 123 is accepted, and false is rejected. The standard 487 errors to produce when evaluating false against this schema are: 489 [{ "instancePath": "", "schemaPath": "/definitions/a/type" }] 491 Though non-root definitions are not syntactically disallowed in 492 correct schemas, they are entirely immaterial to evaluating 493 references. 495 3.3.3. Type 497 The type form is meant to describe instances whose value is a 498 boolean, number, string, or timestamp ([RFC3339]). 500 If a schema is of the type form, then let _T_ be the value of the 501 member with the name "type": 503 o If _T_ equals "boolean", then the instance is accepted if it 504 equals "true" or "false". 506 o If _T_ equals "number", then the instance is accepted if it is a 507 JSON number. 509 o If _T_ equals "string", then the instance is accepted if it is a 510 JSON string. 512 o If _T_ equals "timestamp", then the instance is accepted if it is 513 a JSON string encoding a timestamp, as defined by [RFC3339]. 515 If the instance is not accepted, then the standard error for this 516 case shall have an "instancePath" pointing to the instance, and a 517 "schemaPath" pointing to the schema member with the name "type". 519 For example: 521 o The schema {"type": "boolean"} accepts false, but rejects 123. 523 o The schema {"type": "number"} accepts 123, but rejects false. 525 o The schema {"type": "string"} accepts "1985-04-12T23:20:50.52Z" 526 and "foo", but rejects 123. 528 o The schema {"type": "timestamp"} accepts 529 "1985-04-12T23:20:50.52Z", but rejects "foo" and 123. 531 To give an example of standardized errors, the standard errors to 532 produce when {"type": "boolean"} is evaluated against 123 is: 534 [{ "instancePath": "", "schemaPath": "/type" }] 536 3.3.4. Enum 538 The enum form is meant to describe instances whose value must be one 539 of a finite, predetermined set of string values. 541 If a schema is of the enum form, then let _E_ be the value of the 542 schema member with the name "enum". The instance is accepted if and 543 only if it is equal to one of the elements of _E_. 545 If the instance is not accepted, then the standard error for this 546 case shall have an "instancePath" pointing to the instance, and a 547 "schemaPath" pointing to the schema member with the name "enum". 549 For example, the schema: 551 { "enum": ["PENDING", "DONE", "CANCELED"] } 553 Accepts "PENDING", "DONE", and "CANCELED", but it rejects both 123 554 and "UNKNOWN" with the standard errors: 556 [{ "instancePath": "", "schemaPath": "/enum" }] 558 3.3.5. Elements 560 The elements form is meant to describe instances instances that must 561 be arrays. A further sub-schema describes the elements of the array. 563 If a schema is of the elements form, then let _S_ be the value of the 564 schema member with the name "elements". The instance is accepted if 565 and only if all of the following are true: 567 o The instance is an array. Otherwise, the standard error for this 568 case shall have an "instancePath" pointing to the instance, and a 569 "schemaPath" pointing to the schema member with the name 570 "elements". 572 o If the instance is an array, then every element of the instance 573 must be accepted by _S_. Otherwise, the standard errors for this 574 case are the union of all the errors arising from evaluating _S_ 575 against elements of the instance. 577 For example, if we have the schema: 579 { 580 "elements": { 581 "type": "number" 582 } 583 } 585 Then the instances [] and [1, 2, 3] are accpeted. If instead we 586 evaluate false against that schema, the standard errors are: 588 [{ "instancePath": "", "schemaPath": "/elements" }] 590 Finally, if we evaluate the instance: 592 [1, 2, "foo", 3, "bar"] 594 The standard errors are: 596 [ 597 { "instancePath": "/2", "schemaPath": "/elements/type" }, 598 { "instancePath": "/4", "schemaPath": "/elements/type" } 599 ] 601 3.3.6. Properties 603 The properties form is meant to describe JSON objects being used as a 604 "struct". 606 If a schema is of the properties form, then the instance is accepted 607 if and only if all of the following are true: 609 o The instance is an object. 611 Otherwise, the standard error for this case shall have an 612 "instancePath" pointing to the instance, and a "schemaPath" 613 pointing to the schema member with the name "properties" if such a 614 schema member exists; if such a member doesn't exist, "schemaPath" 615 shall point to the schema member with the name 616 "optionalProperties". 618 o If the instance is an object and the schema has a member named 619 "properties", then let _P_ be the value of the schema member named 620 "properties". _P_, by Section 2, must be an object. For every 621 member name in _P_, a member of the same name in the instance must 622 exist. 624 Otherwise, the standard error for this case shall have an 625 "instancePath" pointing to the instance, and a "schemaPath" 626 pointing to the member of _P_ failing the requirement just 627 described. 629 o If the instance is an object, then let _P_ be the value of the 630 schema member named "properties" (if it exists), and _O_ be the 631 value of the schema member named "optionalProperties" (if it 632 exists). 634 For every member _I_ of the instance, find a member with the same 635 name as _I_'s in _P_ or _O_. By Section 2, it is not possible for 636 both _P_ and _O_ to have such a member. If the "discriminator tag 637 exemption" is in effect on _I_ (see Section 3.3.8), then ignore 638 _I_. Otherwise: 640 * If no such member in _P_ or _O_ exists and validation is using 641 strict instance semantics, then the instance is rejected. 643 The standard error for this case has an "instancePath" pointing 644 _I_, and a "schemaPath" pointing to the schema. 646 * If such a member in _P_ or _O_ does exist, then call this 647 member _S_. If _S_ rejects _I_'s value, then the instance is 648 rejected. 650 The standard error for this case is the union of the errors 651 from evaluating _S_ against _I_'s value. 653 An instance may have multiple errors arising from the second and 654 third bullet in the above. In this case, the standard errors are the 655 union of the errors. 657 For example, if we have the schema: 659 { 660 "properties": { 661 "a": { "type": "string" }, 662 "b": { "type": "string" } 663 }, 664 "optionalProperties": { 665 "c": { "type": "string" }, 666 "d": { "type": "string" } 667 } 668 } 670 Then each of the following instances (one on each line) are accepted: 672 { "a": "foo", "b": "bar" } 673 { "a": "foo", "b": "bar", "c": "baz" } 674 { "a": "foo", "b": "bar", "c": "baz", "d": "quux" } 675 { "a": "foo", "b": "bar", "d": "quux" } 677 If we evaluate the instance 123 against this schema, then the 678 standard errors are: 680 [{ "instancePath": "", "schemaPath": "/properties" }] 682 If instead we evalute the instance: 684 { "b": 3, "c": 3, "e": 3 } 686 The standard errors, using strict instance semantics, are: 688 [ 689 { "instancePath": "", 690 "schemaPath": "/properties/a" }, 691 { "instancePath": "/b", 692 "schemaPath": "/properties/b/type" }, 693 { "instancePath": "/c", 694 "schemaPath": "/optionalProperties/c/type" }, 695 { "instancePath": "/e", 696 "schemaPath": "" } 697 ] 699 If we the same instance were evaluated, but without strict instance 700 semantics, the final element of the above array of errors would not 701 be present. 703 3.3.7. Values 705 The elements form is meant to describe instances that are JSON 706 objects being used as an associative array. 708 If a schema is of the values form, then let _S_ be the value of the 709 schema member with the name "values". The instance is accepted if 710 and only if all of the following are true: 712 o The instance is an object. Otherwise, the standard error for this 713 case shall have an "instancePath" pointing to the instance, and a 714 "schemaPath" pointing to the schema member with the name "values". 716 o If the instance is an object, then every member value of the 717 instance must be accepted by _S_. Otherwise, the standard errors 718 for this case are the union of all the errors arising from 719 evaluating _S_ against member values of the instance. 721 For example, if we have the schema: 723 { 724 "values": { 725 "type": "number" 726 } 727 } 729 Then the instances {} and {"a": 1, "b": 2} are accpeted. If instead 730 we evaluate false against that schema, the standard errors are: 732 [{ "instancePath": "", "schemaPath": "/values" }] 734 Finally, if we evaluate the instance: 736 { "a": 1, "b": 2, "c": "foo", "d": 3, "e": "bar" } 738 The standard errors are: 740 [ 741 { "instancePath": "/c", "schemaPath": "/values/type" }, 742 { "instancePath": "/e", "schemaPath": "/values/type" } 743 ] 745 3.3.8. Discriminator 747 The discriminator form is meant to describe JSON objects being used 748 in a fashion similar to a discriminated union construct in C-like 749 languages. When a schema is of the "discriminator" form, it 750 validates: 752 o That the instance is an object, 754 o That the instance has a particular "tag" property, 756 o That this "tag" property's value is a string within a set of valid 757 values, and 759 o That the instance satisfies another schema, where this other 760 schema is chosen based on the value of the "tag" property. 762 The behavior of the discriminator form is more complex than the other 763 keywords. Readers familiar with CDDL may find the final example in 764 Appendix A helpful in understanding its behavior. What follows here 765 is an English description of the discriminator form's behavior, as 766 well as some examples. 768 If a schema is of the "discriminator" form, then: 770 o Let _D_ be the schema member with the name "discriminator". 772 o Let _T_ be the member of _D_ with the name "tag". 774 o Let _M_ be the member of _D_ with the name "mapping". 776 o Let _I_ be the instance member whose name equals _T_'s value. _I_ 777 may, for some rejected instances, not exist. 779 o Let _S_ be the member of _M_ whose name equals _I_'s value. _S_ 780 may, for some rejected instances, not exist. 782 The instance is accepted if and only if: 784 o The instance is an object. 786 Otherwise, the standard error for this case shall have an 787 "instancePath" pointing to the instance, and a "schemaPath" 788 pointing to _D_. 790 o If the instance is a JSON object, then _I_ must exist. 792 Otherwise, the standard error for this case shall have an 793 "instancePath" pointing to the instance, and a "schemaPath" 794 pointing to _T_. 796 o If the instance is a JSON object and _I_ exists, _I_'s value must 797 be a string. 799 Otherwise, the standard error for this case shall have an 800 "instancePath" pointing to _I_, and a "schemaPath" pointing to 801 _T_. 803 o If the instance is a JSON object and _I_ exists and has a string 804 value, then _S_ must exist. 806 Otherwise, the standard error for this case shall have an 807 "instancePath" pointing to _I_, and a "schemaPath" pointing to 808 _M_. 810 o If the instance is a JSON object, _I_ exists, and _S_ exists, then 811 the instance must satisfy _S_'s value. By Section 2, _S_'s value 812 must have the properties form. Apply the "discriminator tag 813 exemption" afforded in Section 3.3.6 to _I_ when evaluating 814 whether the instance satisfies _S_'s value. 816 Otherwise, the standard errors for this case shall be standard 817 errors from evaluating _S_'s value against the instance. 819 Each of the list items above are defined to be mutually exclusive. 820 For the same instance and schema, only one of the list items above 821 will apply. 823 To illustrate the discriminator form, if we have the schema: 825 { 826 "discriminator": { 827 "tag": "version", 828 "mapping": { 829 "v1": { 830 "properties": { 831 "a": { "type": "number" } 832 } 833 }, 834 "v2": { 835 "properties": { 836 "a": { "type": "string" } 837 } 838 } 839 } 840 } 841 } 843 Then if we evaluate the instance: 845 "example" 846 Against this schema, the standard errors are: 848 [{ "instancePath": "", "schemaPath": "/discriminator" }] 850 (This is the case of the instance not being an object.) 852 If we instead evaluate the instance: 854 {} 856 Then the standard errors are: 858 [{ "instancePath": "", "schemaPath": "/discriminator/tag" }] 860 (This is the case of _I_ not existing.) 862 If we instead evaluate the instance: 864 { "version": 1 } 866 Then the standard errors are: 868 [{ "instancePath": "/version", "schemaPath": "/discriminator/tag" }] 870 (This is the case of _I_ existing, but having a string value.) 872 If we instead evaluate the instance: 874 { "version": "v3" } 876 Then the standard errors are: 878 [ 879 { "instancePath": "/version", 880 "schemaPath": "/discriminator/mapping" } 881 ] 883 (This is the case of _I_ existing and having a string value, but _S_ 884 not existing.) 886 If the instance evaluated were: 888 { "version": "v2", "a": 3 } 890 Then the standard errors are: 892 [ 893 { 894 "instancePath": "/a", 895 "schemaPath": "/discriminator/mapping/v2/properties/a/type" 896 } 897 ] 899 (This is the case of _I_ and _S_ existing, but the instance not 900 satisfying _S_'s value.) 902 Finally, if instead the instance were: 904 { "version": "v2", "a": "foo" } 906 Then the instance satisfies the schema. No standard errors are 907 returned. This would be the case even if evaluation were using 908 strict instance semantics, as the "discriminator tag exemption" would 909 ensure that "version" is not treated as an unexpected property when 910 evaluating the instance against _S_'s value. 912 4. IANA Considerations 914 No IANA considerations. 916 5. Security Considerations 918 Implementations of JSON Schema Language will necessarily be 919 manipulating JSON data. Therefore, the security considerations of 920 [RFC8259] are all relevant here. 922 Implementations which evaluate user-inputted schemas SHOULD implement 923 mechanisms to detect, and abort, circular references which might 924 cause a naive implementation to go into an infinite loop. Without 925 such mechanisms, implementations may be vulnerable to denial-of- 926 service attacks. 928 6. Normative References 930 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 931 Requirement Levels", BCP 14, RFC 2119, 932 DOI 10.17487/RFC2119, March 1997, 933 . 935 [RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet: 936 Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, 937 . 939 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 940 Resource Identifier (URI): Generic Syntax", STD 66, 941 RFC 3986, DOI 10.17487/RFC3986, January 2005, 942 . 944 [RFC6901] Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., 945 "JavaScript Object Notation (JSON) Pointer", RFC 6901, 946 DOI 10.17487/RFC6901, April 2013, 947 . 949 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 950 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 951 May 2017, . 953 [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 954 Interchange Format", STD 90, RFC 8259, 955 DOI 10.17487/RFC8259, December 2017, 956 . 958 Appendix A. Comparison with CDDL 960 This appendix is informative. 962 To aid the reader familiar with CDDL, this section illustrates how 963 JSL works by presenting JSL schemas and CDDL schemas which accept and 964 reject the same instances. 966 The JSL schema {} accepts the same instances as the CDDL rule: 968 root = any 970 The JSL schema: 972 { 973 "definitions": { 974 "a": { "elements": { "ref": "b" }}, 975 "b": { "type": "number" } 976 }, 977 "elements": { 978 "ref": "a" 979 } 980 } 982 Corresponds to the CDDL schema: 984 root = [* a] 986 a = [* b] 987 b = number 989 The JSL schema: 991 { "enum": ["PENDING", "DONE", "CANCELED"]} 993 Accepts the same instances as the CDDL rule: 995 root = "PENDING" / "DONE" / "CANCELED" 997 The JSL schema {"type": "boolean"} corresponds to the CDDL rule: 999 root = bool 1001 The JSL schema {"type": "number"} corresponds to the CDDL rule: 1003 root = number 1005 The JSL schema {"type": "string"} corresponds to the CDDL rule: 1007 root = tstr 1009 The JSL schema {"type": "timestamp"} corresponds to the CDDL rule: 1011 root = tdate 1013 The JSL schema: 1015 { "elements": { "type": "number" }} 1017 Corresponds to the CDDL rule: 1019 root = [* number] 1021 The JSL schema: 1023 { 1024 "properties": { 1025 "a": { "type": "boolean" }, 1026 "b": { "type": "number" } 1027 }, 1028 "optionalProperties": { 1029 "c": { "type": "string" }, 1030 "d": { "type": "timestamp" } 1031 } 1032 } 1034 Corresponds to the CDDL rule: 1036 root = { a: bool, b: number, ? c: tstr, ? d: tdate } 1038 The JSL schema: 1040 { "values": { "type": "number" }} 1042 Corresponds to the CDDL rule: 1044 root = { * tstr => number } 1046 Finally, the JSL schema: 1048 { 1049 "discriminator": { 1050 "tag": "a", 1051 "mapping": { 1052 "foo": { 1053 "properties": { 1054 "b": { "type": "number" } 1055 } 1056 }, 1057 "bar": { 1058 "properties": { 1059 "b": { "type": "string" } 1060 } 1061 } 1062 } 1063 } 1064 } 1066 Corresponds to the CDDL rule: 1068 root = { a: "foo", b: number } / { a: "bar", b: tstr } 1070 Acknowledgments 1072 Thanks to Gary Court, Francis Galiegue, Kris Zyp, Geraint Luff, Jason 1073 Desrosiers, Daniel Perrett, Erik Wilde, Ben Hutton, Evgeny 1074 Poberezkin, Brad Bowman, Gowry Sankar, Donald Pipowitch, Dave Finlay, 1075 Denis Laxalde, Henry Andrews, and Austin Wright for their work on the 1076 initial drafts of JSON Schema, which inspired JSON Schema Language. 1078 Thanks to Tim Bray and Carsten Bormann for their help on JSON Schema 1079 Language. 1081 Author's Address 1083 Ulysse Carion 1085 Email: ulyssecarion@gmail.com