Prototype Specification - DSS 6 | Data Source Solutions Documentation

Documentation: Prototype Specification - DSS 6 | Data Source Solutions Documentation

Prototype Specification

In Data Source Solutions DSS, a "prototype" is a pattern used to specify a complex object, such as the JSON body of a REST request or REST response. Prototype checking implemented inside DSS and prototypes are used to describe and document DSS REST-calls. This is because their range of types is tailored for DSS and (compared to alternatives) they have a concise and powerful grammar.

Syntax

A prototype can contain the following:

Syntax Description
TYPE? Matches element if it occurs zero or one times.
TYPE* Matches element if it occurs zero, one or more times.
TYPE+ Matches element if it occurs one or more times.
(TYPES) Matches an array (list).
{KEY : TYPE [STUFF]} Matches a JSON object such as {"a":1,"b":2} or an array of name/value arrays such as [["a",1],["b",2]].
{KEY ?: TYPE [STUFF]} Matches a JSON object except KEY is optional.
{name<str> *: TYPE} Matches a JSON object with key (name) can occur zero, one or multiple times. For example prototype {table<str> *: <int>} matches JSON {"tab":33, "tbl2":0, "x":99}.
{name<str> +: TYPE} Similar to *: except the key must occur one or more times, it is not optional.
TYPE1|TYPE2 Matches if either TYPE1 or TYPE2 matches.
<str> Matches any string.
<str aa bb> Matches strings aa and bb.
'aa' Matches string aa. Same as <str aa>.
<ident> Identifiers are strings which start with alphabetic or underscore, followed by alphanumeric or underscore.
<other> Matches any name not yet used in {} object.
<int> A 32-bit integer (between -2,147,483,648 and 2,147,483,647).
<bool> Matches integers 0, 1 as well as JSON's true and false.
<int64_ascii> Matches an ASCII string containing a 64-bit integer.
<float64_ascii> Matches an ASCII string containing a float number.
<date_int> An "epoch integer" representing the number of seconds since midnight 1970, UTC. It also matches ISO 8601 format's UTC style, such as "2018-02-05T12:20:00Z".
<date_str_z> Matches a date/time in ISO 8601 format's UTC style, such as "2018-02-05T12:20:00Z". It also matches "epoch integers" representing the number of seconds since midnight 1970, UTC.
<date_str_usecs_z> Matches a date/time in ISO 8601 format’s UTC style including microseconds, such as "2018-02-05T12:20:00.123Z". It also matches "microsecond epoch integers" representing the number of microseconds since midnight 1970, UTC.
<scal> Matches anything except an array (list) or JSON object.
<list> Matches any array (list) or JSON object.
<null MAGIC> Matches JSON's null. Value MAGIC (either &0, (), NUM or STR) controls how the values coerced to a list.
<any> Matches any element.
[-x ] Matches a single-letter POSIX-style command-line option, such as ["-x"].
[-x TYPE] Matches a POSIX-style command-line option with an argument such as ["-x", 22].
[OPTIONS] -- TYPES The double-hyphen signifies the end of POSIX-style command-line option matching.

Prototype Coercion

Prototypes support coercion, so if a REST call has request prototype (<int>*) is called with JSON [1, "2", 3] then it will coerce the request to list of integers, rather than give an mismatch. Likewise, REST endpoints with types <date_int> and <date_str_z> can both be supplied either 59 or "1970-01-01T00:00:59Z"

Examples

  • Example 1: Prototype (<int>*) matches JSON [2, 3, 4]

    Here,

    • <int> matches any integer
    • * means that integer must occur zero or more times
    • () means the whole thing must be in an array. So arrays are () in prototypes, not [].

  • Example 2: Prototype ((tabid<int>+) {'fname':<str> 'readonly' ?:<bool>}) matches JSON [[2, 3], {"fname":"/tmp/xx", "readonly":false}]

    Here,

    • Type <int> is preceded by a name tabid. See this as a comment, to assist readability.

    • {} in the prototypes matches the JSON object. Note that no comma is used.

    • The prototype has literal strings like 'fname' but these are single-quoted, whereas JSON uses double-quotes.

    • This prototype does not match JSON [[], {"fname":"xx", "readonly":false}] because (<int>+) means the array needs one of more objects. It would match prototype contained (<int>*) instead.

    • The prototype has ?: so key "readonly" is optional and therefore matches [[2, 3], {"fname":"/tmp/xx"}] but not [[2, 3], {"readonly":false}]

    • The prototype matches [[2, 3], {"readonly":false, "fname":"/tmp/xx"}] because the order of attributes in a JSON object is not significant.

    • This prototype does not match [[2, 3], {"fname":"xx", "readwrite": true}] because attribute "readwrite" is not a named in the prototype. Matching of extra attributes is allowed if <other> is added, for example prototype {'fname':<str> 'readonly'?:<bool> <other>?:<any>}.