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 nametabid. 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>}.
-