idnits 2.17.1 draft-cordell-jcr-co-constraints-00.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 document seems to lack a Security Considerations section. ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** The abstract seems to contain references ([JCR], [RFC7159]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. RFC 2119 keyword, line 73: '... A JCR processor MAY ignore the JCRCC ...' RFC 2119 keyword, line 144: '...ith the JCR rule MUST be present, othe...' RFC 2119 keyword, line 375: '...sociated with it MUST be represented u...' RFC 2119 keyword, line 383: '...associated with the identifier MUST be...' RFC 2119 keyword, line 388: '...capture function MUST include a captur...' Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (March 21, 2016) is 2956 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Possible downref: Non-RFC (?) normative reference: ref. 'JCR' ** Obsolete normative reference: RFC 7159 (Obsoleted by RFC 8259) Summary: 5 errors (**), 0 flaws (~~), 1 warning (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group P. Cordell 3 Internet-Draft Codalogic 4 Intended status: Standards Track A. Newton 5 Expires: September 22, 2016 ARIN 6 March 21, 2016 8 Co-Constraints for JSON Content Rules 9 draft-cordell-jcr-co-constraints-00 11 Abstract 13 JSON Content Rules (JCR) [JCR] provides a powerful, intuitive and 14 concise method for defining the structure of JSON [RFC7159] messages. 15 However, modern JSON usage patterns occasionally mean that JCR alone 16 is not able to capture the required constraints in a satisfactory 17 way. This document describes JCR Co-Constraints (JCRCC) which 18 defines additional JCR directives and annotations that can be added 19 to a JCR ruleset in order to define more detailed constraints on JSON 20 messages. 22 Status of This Memo 24 This Internet-Draft is submitted in full conformance with the 25 provisions of BCP 78 and BCP 79. 27 Internet-Drafts are working documents of the Internet Engineering 28 Task Force (IETF). Note that other groups may also distribute 29 working documents as Internet-Drafts. The list of current Internet- 30 Drafts is at http://datatracker.ietf.org/drafts/current/. 32 Internet-Drafts are draft documents valid for a maximum of six months 33 and may be updated, replaced, or obsoleted by other documents at any 34 time. It is inappropriate to use Internet-Drafts as reference 35 material or to cite them other than as "work in progress." 37 This Internet-Draft will expire on September 22, 2016. 39 Copyright Notice 41 Copyright (c) 2016 IETF Trust and the persons identified as the 42 document authors. All rights reserved. 44 This document is subject to BCP 78 and the IETF Trust's Legal 45 Provisions Relating to IETF Documents 46 (http://trustee.ietf.org/license-info) in effect on the date of 47 publication of this document. Please review these documents 48 carefully, as they describe your rights and restrictions with respect 49 to this document. Code Components extracted from this document must 50 include Simplified BSD License text as described in Section 4.e of 51 the Trust Legal Provisions and are provided without warranty as 52 described in the Simplified BSD License. 54 1. Introduction 56 JSON Content Rules [JCR] provides a powerful, intuitive and concise 57 method for defining the structure of JSON [RFC7159] messages. In 58 addition to describing the overall structure of JSON messages, JCR 59 aims to capture the constraints that are imposed on individual items 60 within a message. However, modern JSON usage occasionally requires 61 constraints that can't be expressed by JCR alone. JCR Co-Constraints 62 (JCRCC) defines additional JCR directives and annotations that can be 63 added to a JCR ruleset in order to define more detailed constraints 64 on items within a JSON message, and also supports specifying 65 constraints that depend on the relationship of multiple JSON items. 67 JCRCC constraints represent an additional layer of validation on top 68 of the validation provided by JCR alone. JCRCC constraints may 69 indicate that a JSON instance that was determined to be valid by the 70 rules of a JCR ruleset is in fact invalid. However, if the JCR 71 ruleset indicates that the JSON instance is invalid, JCRCC 72 constraints can not override that and declare the instance to be 73 valid. A JCR processor MAY ignore the JCRCC annotations and 74 directives, perhaps only issuing a warning for encountering an 75 unknown annotation or directive. 77 JCRCC uses the annotations @{id}, @{when} and @{assert} along with 78 the directive #{constraint}. The @{id} annotation is used to 79 identify an item in a JSON message that contributes to the assessment 80 of a JSON instance's validity. The other three each include a 81 'condition' expression that yields a Boolean true or false result. 82 The validity of the JSON instance is dependent on the results of the 83 various condition expressions. Condition expressions are made up of 84 identifiers, comparators, combiners and functions. Each of these 85 aspects is described in more detail below. 87 2. Definitions 89 Assessment - 90 The process whereby it is determined whether a JSON instance is 91 valid according to a JCR ruleset (which may or may not include 92 JCR co-constraints). 94 JSON instance - 95 A JSON message that is being validated against a JCR ruleset 96 (which may augmented using JCRCC). 98 JSON instance item - 99 An object member or a value in a JSON instance. Often JCRCC 100 annotations will define an identifier that will be associated 101 with a JSON instance item. 103 3. Annotations and Directives 105 JCRCC uses the annotations @{id}, @{when} and @{assert} plus the 106 directive #{constraint}. 108 3.1. The @{id} Annotation 110 The @{id} annotation creates an identifier for a rule in a JCR 111 ruleset. A maximum of one @{id} annotation is permitted per rule. 112 It has the form: 114 @{id name} 116 where 'name' corresponds to the 'name' production in the JCR ABNF. 118 The @{id} annotation associates an identifier with the rule on which 119 it is placed. The identifier can then be used in condition 120 expressions to reference the corresponding item in JSON instance 121 items that are mapped to the JCR rule during validation. 123 For example, a JCR rule of: 125 "type" @{id t} : string 127 might associate the identifier 't' with a JSON instance item such as: 129 "type" : "shutdown" 131 3.2. The @{when} Annotation 133 The @{when} annotation has two similar roles. If a JCR rule 134 indicates that a JSON instance item is optional, then it can be used 135 to describe the conditions when the item is present or absent. 136 Similarly, if a JCR rule indicates that an item has a choice of 137 types, then the @{when} annotation can be used to indicate which of 138 the possible sub-rules is applicable in the current validation 139 instance. Only one @{when} annotation per rule is permitted. 141 The @{when} annotation includes a single 'condition'. In the case of 142 using the @{when} annotation with an optional instance, if the 143 condition yields a 'true' result, then the JSON instance item 144 associated with the JCR rule MUST be present, otherwise it MUST be 145 absent. 147 When the @{when} annotation is used to select the applicable member/ 148 type rule within a group or type choice, the condition of each 149 @{when} annotation is evaluated in turn (from left to right as shown 150 in the JCR rule) and the member/type rule that corresponds to the 151 first @{when} condition that yields a 'true' result is selected. If 152 none of the @{when} annotations on a group or type choice yields 153 true, this indicates an invalid instance. When a member/type rule 154 within a group or type choice that has @{when} annotations on other 155 members/types, but does not itself have an @{when} annotation, this 156 indicates the default case. In essence, if a rule contains @{when} 157 annotations, then an absent @{when} annotation on a member/type rule 158 is equivalent to @{when true}. 160 As an example, a @{when} annotation on an optional item may look as 161 follows: 163 ? @{when $t == "shutdown"} "uptime" : integer 165 This indicates that the "uptime" member should be present if the JSON 166 instance item associated with a JCR rule with an @{id t} annotation 167 has the value "shutdown". 169 A @{when} annotation on a group may look as follows: 171 details ( @{when $t == "boot"} boot-details | 172 @{when $t == "shutdown"} shutdown-details | 173 default-details ) 175 This indicates that the JCR rule named 'boot-details' is applicable 176 when the JSON instance item associated with an @{id t} annotation has 177 the value "boot", the rule 'shutdown-details' is applicable when the 178 value of the $t item is "shutdown", otherwise the rule 'default- 179 details' is applicable. (The rules identified by 'boot-details', 180 'shutdown-details' and 'default-details' might be groups that act as 181 mixins for the rule in which the 'details' rule is used.) 183 The @{when} annotation can reference identifiers in siblings, 184 ancestors, and descendants. To avoid circular or ambiguous 185 dependencies, the identifiers in descendants must not be part of 186 arrays or descendants of itself or descendants of siblings that have 187 @{when} annotations. The latter restriction avoids needing to know 188 whether a secondary @{when} annotation yields 'true' in order to 189 determine if the @{when} annotation being assessed yields 'true'. 190 When seeking identifiers, siblings are inspected first, followed by 191 the nearest ancestor, followed by the nearest descendent. If it is 192 desired to look for an identifier that is a descendent without first 193 looking for an identifier that is an ancestor, then the 194 'descendent()' method can be called on the name of the identifier. 195 For example: 197 ? @{when descendent($s) == "on"} "watts" : integer 199 3.3. The @{assert} Annotation 201 The @{assert} annotation is used to specify additional constraints on 202 an item that can't be expressed using JCR alone. The @{assert} 203 annotation contains a single condition that must yield 'true' for the 204 JSON instance item to be considered valid. A maximum of one 205 @{assert} annotations is permitted per rule. 207 @{assert} annotations are evaluated after all sibling @{when} 208 annotations have been evaluated, and constraints specified by the 209 underlying JCR rule have been assessed. An item may have both a 210 @{when} annotation and a @{assert} annotation. If the condition in 211 the @{when} annotation yields 'false', then the item it corresponds 212 to should be absent in the JSON instance, so the @{assert} condition 213 is not evaluated. If the JSON instance item is not valid according 214 the underlying JCR rule, then validation fails at that point and the 215 @{assert} annotation is not assessed. 217 When seeking identifiers referenced in an @{assert} annotation, 218 siblings are inspected first, followed by the nearest ancestor, 219 followed by the nearest descendent. If it is desired to look for an 220 identifier that is a descendent without first looking for an 221 identifier that is an ancestor, then the 'descendent()' method can be 222 called on the name of the identifier. 224 An example @{assert} annotation might be: 226 "index" @{assert $ % 2 == 0} : integer ; Must be even 228 3.4. The #{constraint} Directive 230 The #{constraint} directive offers a way to express conditions 231 external to @{when} and @{assert} annotations. #{constraint} 232 directives can be viewed as a macro substitution mechanism. @{when} 233 and @{assert} annotations, and other #{constraint} directives can 234 reference conditions defined by a #{constraint}. The format of a 235 #{constraint} directive is as follows: 237 #{constraint name condition} 239 where 'name' corresponds to the 'name' production in the JCR ABNF, 240 and the 'condition' is the same as used in @{when} and @{assert} 241 annotations and is as described below. 243 Conceptually at least, the 'condition' in a #{constraint} directive 244 is substituted into @{when}, @{assert} annotations and other 245 #{constraint} directives wherever the constraint's 'name' is 246 referenced. (In practice, for the purposes of efficiency, the result 247 of a #{constraint} directive may be cached or memoized, to avoid 248 repeated computation of the sub-condition. However, such 249 optimizations are beyond the scope of this document.) 251 An example usage, equating to the earlier example, might be: 253 #{constraint is_even $ % 2 == 0} 254 "index" @{assert @is_even} : integer ; Must be even 256 4. Conditions 258 The @{when} annotation, @{assert} annotation and #{constraint} 259 directive contain 'conditions'. These are made up of 'identifiers', 260 'comparators', 'combiners' and 'functions' as described below. 262 4.1. Identifiers 264 Identifiers are used to refer to items in the JCR, and #{constraint} 265 directives. They have a few different forms. 267 '$' on its own refers to the member / type expressed by the current 268 JCR rule. For example: 270 int-pairs @{assert count( $ ) % 2 == 0} [ : integer ] 272 The form '$name' and '$alias.name' form is an item reference and 273 refers to members and types identified by JCR rules by @{id} 274 annotations. An 'alias' is set up using the normal JCR #import 275 directive and allows members / types outside the current ruleset to 276 be identified. For example: 278 @{id type} : string, { 279 ? "uptime" @{when $type == "shutdown"} : integer } 281 An item reference that is not part of an 'operator' or a 'comparator' 282 sub-expression yields 'true' if the referenced item is present in the 283 JSON instance being validated, and 'false' if not. For example, the 284 following says that the 'dob' member must be present if the 'name' 285 member is present: 287 ? "name" @{id n} : string, 288 ? "dob" @{when $n} : full-date 290 An item reference that is part of an 'operator' or a 'comparator' 291 sub-expression yields the value of the corresponding JSON instance 292 item. 294 Item references may also be used as arguments to functions. 296 The '@name' and '@alias.name' form is a constraint reference and 297 refers to a condition expressed in a #{constraint} directive. An 298 'alias' is set up using the normal JCR #import directive and allows 299 constraints outside the current ruleset to be identified. For 300 example: 302 #{constraint is_even $ % 2 == 0} 303 "index" : @{assert @is_even} integer ; Must be even 305 4.2. Operators 307 The values of JSON instance items identified by identifiers, values 308 yielded by other 'operators' and values returned by 'functions' can 309 be subject to computations using 'operators'. The supported 310 operators are '+', '-', '*', '/' and '%'. They have their usual 311 C-family programming language meaning. The precedence of the 312 operators is as-per normal mathematics rules. Operators have higher 313 precedence than comparators. 315 4.3. Comparators 317 The values of JSON instance items identified by identifiers, values 318 yielded by 'operators' and values returned by 'functions' can be 319 compared using 'comparators'. The comparators are the usual '<', 320 '<=', '==', '!=', '>=' and '>', and have their usual C-family 321 language meaning. Comparators yield a 'true' or 'false' result. 323 When an identifier referenced by a comparator is absent, then the 324 comparison returns 'false'. For example: 326 $t == "boot" 328 is equivalent to: 330 ( $t && $t == "boot" ) 332 Similarly: 334 $t == "boot" || $other == "close" 336 is equivalent to: 338 ( $t && $t == "boot" ) || ( $other && $other == "close" ) 340 And: 342 length( $first ) > length( $second ) 344 is equivalent to: 346 ( $first && $second && length( $first ) > length( $second ) ) 348 Comparators have higher precedence than combiners. 350 4.4. Combiners 352 Multiple results of 'comparators' or standalone identifiers can be 353 combined using 'combiners'. The supported combiners are '&&' and 354 '||'. They have their usual C-family programming language meaning. 356 4.5. Functions 358 JCRCC supports a number of functions that can be used to yield 359 specific information about a JSON instance item referenced by an 360 identifier. Some functions can operate on multiple types of 361 argument, such as identifiers or strings. In the function 362 descriptions below, arguments that can take multiple different types 363 have each type listed, separated by the pipe symbol (|). For 364 example, an argument description of "identifier | string" indicates 365 that the function can take an identifier or a string as an argument. 367 The functions are as follows: 369 name( identifier ) - 370 Returns the member name of the JSON instance item associated 371 with the identifier as a string. 373 length( identifier | string ) - 374 If the argument is an identifier, the value of the JSON 375 instance item associated with it MUST be represented using a 376 JSON string (i.e. it could be defined as a JCR ip4 type that is 377 represented in JSON using the string format). The function 378 returns the length of the string in Unicode code points. To 379 return the length of a JSON instance item's member name, do 380 "length( name( $t ) )". 382 count( identifier ) - 383 The JSON instance item associated with the identifier MUST be 384 an array. The function returns the number of items in the 385 array. 387 capture( identifier | string, regex ) - 388 The regex in the capture function MUST include a capture 389 expression (i.e. a suitable term in brackets). The regex is 390 applied to the input string, or the string value of the JSON 391 instance item associated with the identifier, and the sub- 392 string captured by the regex capture expression is returned. 394 descendent( identifier ) - 395 The normal order of identifier look up is, siblings, followed 396 by ancestors, followed by descendents. This function will 397 cause the lookup to be in the order siblings followed by 398 descendents. It returns a reference to a JSON instance item 399 that can be used in place of an identifier. For example, 400 "length( name( descendent( $t ) ) )". 402 error( q_string ) - 403 This function can be used for reporting error messages. The 404 text in the q_string may be subject to value interpolation and 405 internationalization by an implementation, but this is not 406 required. It always returns false. For example: @{assert 407 $%2==0 || error("value must be even")} :integer 409 is_null( identifier ), is_boolean( identifier ), is_string( 410 identifier ), is_float( identifier ), is_integer( identifier ), 411 is_ip4( identifier ), is_ip6( identifier ), is_fqdn( identifier ), 412 is_idn( identifier ), is_uri( identifier ), is_phone( identifier ), 413 is_email( identifier ), is_full-date( identifier ), is_full-time( 414 identifier ), is_date-time( identifier ), is_base64( identifier ) - 415 This set of functions return true if the JSON instance item 416 associated with the identifier has the corresponding type, and 417 false otherwise. 419 4.6. If-Then-Else 421 5. ABNF 423 The ABNF is 'work in progress'. It currently looks as below. This 424 does not capture where spaces are permitted. 426 condition = relational ( * ( "&&" relational ) / 427 * ( "||" relational ) ) 429 relational = ["!"] value / value comparator value / 430 ["!"] condition-group / ternary 432 value = identifier / constant / function / "@" [ alias "." ] name 434 identifier = "$" / "$" [ alias "." ] name 436 constant = "null" / "true" / "false" / integer / float / 437 q_string / regex 439 comparator = "==" / "!=" / "<" / "<=" / ">=" / ">" 441 condition-group = "(" condition ")" 443 ternary = "if" "(" condition ")" "then" "(" condition ")" 444 "else" "(" condition ")" 446 function = "name" "(" identifier ")" / 447 "length" "(" identifier ")" / 448 "count" "(" identifier ")" / 449 "capture" "(" regex "," identifier ")" / 450 "descendent" "(" identifier ")" / 451 "error" "(" q_string ")" / 452 "is_integer" "(" identifier ")" / 453 "is_float" "(" identifier ")" / 454 etc... 456 6. References 458 6.1. Normative References 460 [JCR] Newton, A. and P. Cordell, "A Language for Rules 461 Describing JSON Content", October 2015, 462 . 465 [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 466 Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March 467 2014, . 469 6.2. Infomative References 471 [ARIN_JCR_VALIDATOR] 472 American Registry for Internet Numbers, "JSON Content 473 Rules Validator (Work In Progress)", 474 . 476 [CODALOGIC_JCR_VALIDATOR] 477 Codalogic, "cl-jcr-parser (Work In Progress)", 478 . 480 Appendix A. JCR Implementations 482 The following implementations, [ARIN_JCR_VALIDATOR] and 483 [CODALOGIC_JCR_VALIDATOR] have influenced the development of this 484 document. 486 Authors' Addresses 488 Pete Cordell 489 Codalogic 490 PO Box 30 491 Ipswitch IP5 2WY 492 UK 494 Email: pete.cordell@codalogic.com 495 URI: http://www.codalogic.com 497 Andrew Lee Newton 498 American Registry for Internet Numbers 499 3635 Concorde Parkway 500 Chantilly, VA 20151 501 US 503 Email: andy@arin.net 504 URI: http://www.arin.net