|
353 | 353 | at runtime, for instance due to application state that controls the operation's |
354 | 354 | availability. |
355 | 355 | </t> |
356 | | - <section title="Resolving templated URIs"> |
357 | | - <t> |
358 | | - URI Template variables in <xref target="href">"href"</xref> resolve from |
359 | | - server-supplied instance data by default. This data is drawn from the |
360 | | - sub-instance that validated against the schema containing the LDO. |
361 | | - </t> |
362 | | - <t> |
363 | | - <xref target="templatePointers">"templatePointers"</xref> allows adjusting |
364 | | - the location from which instance data is resolved on a per-variable |
365 | | - basis. |
366 | | - </t> |
367 | | - <t> |
368 | | - <xref target="hrefSchema">"hrefSchema"</xref> allows a link to specify |
369 | | - a schema for resolving template variables from client-supplied data. |
370 | | - Regular JSON Schema validation features can be used to require resolution |
371 | | - from user agent data, forbid it, or allow user agent data while falling back |
372 | | - to server-supplied instance data if no user agent data is provided. |
373 | | - </t> |
374 | | - <t> |
375 | | - To implement the common pattern of resolving a templated path component |
376 | | - with server-supplied instance data while accepting user agent data to build |
377 | | - a query string: |
378 | | - <list style="symbols"> |
379 | | - <t> |
380 | | - set the "hrefSchema" subschemas for the path template variables |
381 | | - to false, to disallow user agent input |
382 | | - </t> |
383 | | - <t> |
384 | | - give the query string template variables names that do not appear |
385 | | - in the instance, to prevent resolving them from the instance |
386 | | - </t> |
387 | | - </list> |
388 | | - See the "hrefSchema" section for an example of this approach. |
389 | | - </t> |
390 | | - <t> |
391 | | - To implement the equivalent of an input form pre-populated with |
392 | | - pre-existing instance data: |
393 | | - <list style="symbols"> |
394 | | - <t> |
395 | | - ensure that each variable in the form resolves from the appropriate |
396 | | - field in the instance, which provides the initial value that will |
397 | | - continue to be used if the user agent takes no action to change it |
398 | | - </t> |
399 | | - <t> provide a validation schema for each of those fields in |
400 | | - "hrefSchema", to describe what user agent input may be allowed |
401 | | - to replace it |
402 | | - </t> |
403 | | - </list> |
404 | | - This can be done with variables in any component of the URI template |
405 | | - (path, query string, etc.) While the word "form" is used here, |
406 | | - JSON Hyper-Schema does not constraint the nature of this interaction, which |
407 | | - may or may not involve rendering an interactive form. |
408 | | - </t> |
409 | | - </section> |
410 | 356 | <section title="Manipulating the target resource representation"> |
411 | 357 | <t> |
412 | 358 | In JSON Hyper-Schema, <xref target="targetSchema">"targetSchema"</xref> |
|
451 | 397 | This property is REQUIRED. |
452 | 398 | </t> |
453 | 399 |
|
454 | | - <section title="URI Templating"> |
455 | | - <t> |
456 | | - <cref> |
457 | | - The pre-processing rules present in earlier drafts have been removed due |
458 | | - to their complexity and inability to address all limitations with URI |
459 | | - templating. |
460 | | - This section is subject to significant change in upcoming drafts to |
461 | | - replace the old pre-processing with a comprehensive solution. |
462 | | - </cref> |
463 | | - </t> |
464 | | - <t> |
465 | | - The value of "href" is to be used as a URI Template, as defined in |
466 | | - <xref target="RFC6570">RFC 6570</xref>. |
467 | | - However, some special considerations apply: |
468 | | - </t> |
469 | | - |
470 | | - <section title="Values for substitution"> |
471 | | - <t> |
472 | | - The URI Template is filled out using data from some combination of an |
473 | | - external source and the instance. |
474 | | - Where either instance data or user agent data may be used, this section |
475 | | - will refer simply to "data" or to a "value". |
476 | | - When the source is important, it is specified explicitly. |
477 | | - |
478 | | - To allow the use of any object property (including the empty string) or |
479 | | - array index, the following rules are defined: |
480 | | - </t> |
481 | | - |
482 | | - <t> |
483 | | - For a given variable name in the URI Template, the value to use is |
484 | | - determined as follows: |
485 | | - <list> |
486 | | - <t> |
487 | | - If the data is an array, and the variable name is a |
488 | | - representation of a non-negative integer, then the value at the |
489 | | - corresponding array index MUST be used (if it exists). |
490 | | - </t> |
491 | | - <t> |
492 | | - Otherwise, the variable name should be percent-decoded, and the |
493 | | - corresponding object property MUST be used (if it exists). |
494 | | - </t> |
495 | | - </list> |
496 | | - </t> |
497 | | - |
498 | | - <t> |
499 | | - If <xref target="hrefSchema">"hrefSchema"</xref> is present and |
500 | | - user agent data is provided, the data MUST be a valid instance according |
501 | | - to the value of "hrefSchema". |
502 | | - Template variables, after the process listed above, MUST first |
503 | | - be resolved from the user agent data instance. Any variables left |
504 | | - unresolved MUST be resolved from the resource instance data. |
505 | | - </t> |
506 | | - |
507 | | - <section title="Converting to strings"> |
508 | | - <t> |
509 | | - When any value referenced by the URI template is null, a boolean or |
510 | | - a number, then it should first be converted into a string as |
511 | | - follows: |
512 | | - <list> |
513 | | - <t> |
514 | | - null values SHOULD be replaced by the text "null" |
515 | | - </t> |
516 | | - <t> |
517 | | - boolean values SHOULD be replaced by their lower-case |
518 | | - equivalents: "true" or "false" |
519 | | - </t> |
520 | | - <t> |
521 | | - numbers SHOULD be replaced with their original JSON |
522 | | - representation. |
523 | | - </t> |
524 | | - </list> |
525 | | - </t> |
526 | | - <t> |
527 | | - In some software environments the original JSON representation of a |
528 | | - number will not be available (there is no way to tell the difference |
529 | | - between 1.0 and 1), so any reasonable representation should be used. |
530 | | - Schema and API authors should bear this in mind, and use other types |
531 | | - (such as string or boolean) if the exact representation is |
532 | | - important. |
533 | | - </t> |
534 | | - </section> |
535 | | - </section> |
536 | | - |
537 | | - <section title="Missing values" anchor="missingValues"> |
538 | | - <t> |
539 | | - Sometimes, the appropriate values will not be available. In many |
540 | | - cases, the URI Template behavior of simply removing variables that |
541 | | - do not have a value will be appropriate. An example of this is |
542 | | - optional query parameters, the presence or absence of which does |
543 | | - not change the nature of the link relation type. |
544 | | - </t> |
545 | | - |
546 | | - <t> |
547 | | - However, some variables, such as an identifier used in a path component, |
548 | | - cannot meaningfully be omitted. The resulting URI would be meaningless, |
549 | | - or would require a different link relation type. While "hrefSchema" can |
550 | | - express a requirement for those variables that can be supplied via input, |
551 | | - some variables must be resolved from instance data. When that instance |
552 | | - data is not required by the context schema, the |
553 | | - <xref target="templateRequired">"templateRequired</xref> keyword may |
554 | | - be used to indicate that when the instance data is not available, the |
555 | | - link does not apply. |
556 | | - </t> |
557 | | - </section> |
558 | | - </section> |
559 | | - |
560 | 400 | </section> |
561 | 401 |
|
562 | 402 | <section title="templatePointers" anchor="templatePointers"> |
|
676 | 516 | any user agent data from being accepted. |
677 | 517 | </t> |
678 | 518 | <t> |
679 | | - Implementations MUST NOT attempt to validate values resolved from |
680 | | - resource instance data with "hrefSchema". This allows for different |
| 519 | + For template variables that can be resolved from the instance, if |
| 520 | + the variable is NOT: |
| 521 | + <list style="symbols"> |
| 522 | + <t>Present in "properties" with a value of false, OR</t> |
| 523 | + <t>Matching a key in "patternProperties" with a value of false, OR</t> |
| 524 | + <t>Matched by "additionalProperties" with a value of false</t> |
| 525 | + </list> |
| 526 | + then the input data set for that variable SHOULD be pre-populated |
| 527 | + with the value from the instance. |
| 528 | + </t> |
| 529 | + <t> |
| 530 | + Note that even when data is pre-populated from the instance, the validation |
| 531 | + schema for that variable in "hrefSchema" need not match the validation |
| 532 | + schema(s) that apply to the instance data's location. This allows for different |
681 | 533 | validation rules for user agent data, such as supporting spelled-out |
682 | | - months for date-time input but using the standard date-time |
683 | | - format for storage. |
| 534 | + months for date-time input, but using the standard date-time format for storage. |
684 | 535 | </t> |
685 | 536 | <figure> |
686 | 537 | <preamble> |
@@ -1539,6 +1390,128 @@ GET /foo/ |
1539 | 1390 | </t> |
1540 | 1391 | </section> |
1541 | 1392 | </section> |
| 1393 | + <section title="URI Templating"> |
| 1394 | + <t> |
| 1395 | + Three hyper-schema keywords are <xref target="RFC6570">URI Templates</xref>: |
| 1396 | + "base", "anchor", and "href". Each are resolved separately to URI-references, |
| 1397 | + and then the anchor or href URI-reference is resolved against the base (which |
| 1398 | + is itself resolved against earlier bases as needed, each of which was first |
| 1399 | + resolved from a URI Template to a URI-reference). |
| 1400 | + </t> |
| 1401 | + <t> |
| 1402 | + All three keywords share the same algorithm for resolving variables from |
| 1403 | + instance data, which makes use of the "templatePointers" and "templateRequired" |
| 1404 | + keywords. When resolving "href", both it and any "base" templates |
| 1405 | + needed for resolution to an absolute URI, the algorithm is modfied to |
| 1406 | + optionally accept user input based on the "hrefSchema" keyword. |
| 1407 | + </t> |
| 1408 | + <t> |
| 1409 | + For each URI Template (T), the following pseudocode describes an algorithm for |
| 1410 | + resolving T into a URI-reference (R). For the purpose of this algorithm: |
| 1411 | + <list style="symbols"> |
| 1412 | + <t> |
| 1413 | + "ldo.templatePointers" is an empty object if the keyword was not |
| 1414 | + present and "ldo.templateRequired" is likewise an empty array. |
| 1415 | + </t> |
| 1416 | + <t> |
| 1417 | + "attachmentPointer" is the absolute JSON Pointer for the attachment |
| 1418 | + location of the LDO. |
| 1419 | + </t> |
| 1420 | + <t> |
| 1421 | + "getApplicableSchemas()" returns an iterable set of all (sub)schemas |
| 1422 | + that apply to the attachment point in the instance. |
| 1423 | + </t> |
| 1424 | + <t> |
| 1425 | + "InputForm" represents whatevers sort of input mechanism is appropriate. |
| 1426 | + This may be a literal web form, or may be a more programmatic construct |
| 1427 | + such as a callback funciton accepting specific fields and data types, |
| 1428 | + with the given initial values, if any. |
| 1429 | + </t> |
| 1430 | + </list> |
| 1431 | + </t> |
| 1432 | + <figure> |
| 1433 | + <preamble> |
| 1434 | + This algorithm should be applied first to either "href" or "anchor", |
| 1435 | + and then as needed to each successive "base". The order is important, |
| 1436 | + as it is not always possible to tell whether a template will resolve |
| 1437 | + to a full URI or a URI-reference. |
| 1438 | + </preamble> |
| 1439 | + <artwork> |
| 1440 | +<![CDATA[ |
| 1441 | +templateData = {} |
| 1442 | +
|
| 1443 | +for varname in T: |
| 1444 | + varname = rfc3986PercentDecode(varname) |
| 1445 | + if varname in ldo.templatePointers: |
| 1446 | + valuePointer = templatePointers[varname] |
| 1447 | + if valuePointer is relative: |
| 1448 | + valuePointer = resolveRelative(attachmentPointer, |
| 1449 | + valuePointer) |
| 1450 | + else |
| 1451 | + valuePointer = attachmentPointer + "/" + varname |
| 1452 | +
|
| 1453 | + value = instance.valueAt(valuePointer) |
| 1454 | + if value is defined: |
| 1455 | + templateData[varname] = value |
| 1456 | +
|
| 1457 | +if resolving "href" and ldo.hrefSchema exists: |
| 1458 | +
|
| 1459 | + form = new InputForm() |
| 1460 | + for varname in T: |
| 1461 | + usable = true |
| 1462 | + for schema in getApplicableSchemas(ldo.hrefSchema, |
| 1463 | + "/" + varname): |
| 1464 | + if schema is false or ( |
| 1465 | + varname in templateData and |
| 1466 | + not isValid(templateData[varname], schema)): |
| 1467 | +
|
| 1468 | + usable = false |
| 1469 | + break |
| 1470 | + |
| 1471 | + if usable: |
| 1472 | + form.addInputFieldFor(ldo.hrefSchema, |
| 1473 | + varname, |
| 1474 | + templateData[varname]) |
| 1475 | + inputData = form.acceptInput() |
| 1476 | +
|
| 1477 | + if not validate(inputData, hrefSchema): |
| 1478 | + fatal("Input invalid, link is not usable") |
| 1479 | +
|
| 1480 | + for varname in inputData: |
| 1481 | + templateData[varname] = inputData[varname] |
| 1482 | +
|
| 1483 | +for varname in ldo.templateRequired: |
| 1484 | + if not exists templateData[varname] |
| 1485 | + fatal("Missing required variable(s)") |
| 1486 | +
|
| 1487 | +for varname in templateData: |
| 1488 | + value = templateData[varname] |
| 1489 | + if value is true: |
| 1490 | + templateData[varname] = "true" |
| 1491 | + else if value is false: |
| 1492 | + temlateData[varname] = "false" |
| 1493 | + else if value is null: |
| 1494 | + templateData[varname] = "null" |
| 1495 | + else if value is a number: |
| 1496 | + templateData[varname] = |
| 1497 | + bestEffortOriginalJsonString(value) |
| 1498 | + else: |
| 1499 | + templateData[varname] = rfc3986PercentEncode(value) |
| 1500 | +
|
| 1501 | +let R = rfc6570ResolutionAlgorithm(T, templateData) |
| 1502 | +]]> |
| 1503 | + </artwork> |
| 1504 | + <postamble> |
| 1505 | + In some software environments the original JSON representation of a |
| 1506 | + number will not be available (there is no way to tell the difference |
| 1507 | + between 1.0 and 1), so any reasonable representation should be used. |
| 1508 | + Schema and API authors should bear this in mind, and use other types |
| 1509 | + (such as string or boolean) if the exact representation is |
| 1510 | + important. If the number was provide as input in the form of a |
| 1511 | + string, the string used as input SHOULD be used. |
| 1512 | + </postamble> |
| 1513 | + </figure> |
| 1514 | + </section> |
1542 | 1515 |
|
1543 | 1516 | <!-- |
1544 | 1517 | <section title="IANA Considerations"> |
|
0 commit comments