2. Syntax
A URI Template is a string of printable Unicode characters that contains zero or more embedded variable expressions, each expression being delimited by a matching pair of braces ('{', '}').
URI-Template = *( literals / expression )
Although templates (and template processor implementations) are described above in terms of four gradual levels, we define the URI-Template syntax in terms of the ABNF for Level 4. A template processor limited to lower-level templates MAY exclude the ABNF rules applicable only to higher levels. However, it is RECOMMENDED that all parsers implement the full syntax such that unsupported levels can be properly identified as such to the end user.
2.1. Literals
The characters outside of expressions in a URI Template string are intended to be copied literally to the URI reference if the character is allowed in a URI (reserved / unreserved / pct-encoded) or, if not allowed, copied to the URI reference as the sequence of pct-encoded triplets corresponding to that character's encoding in UTF-8 [RFC3629].
literals = %x21 / %x23-24 / %x26 / %x28-3B / %x3D / %x3F-5B
/ %x5D / %x5F / %x61-7A / %x7E / ucschar / iprivate
/ pct-encoded
; any Unicode character except: CTL, SP,
; DQUOTE, "'", "%" (aside from pct-encoded),
; "<", ">", "\", "^", "`", "{", "|", "}"
2.2. Expressions
Template expressions are the parameterized parts of a URI Template. Each expression contains an optional operator, which defines the expression type and its corresponding expansion process, followed by a comma-separated list of variable specifiers (variable names and optional value modifiers). If no operator is provided, the expression defaults to simple variable expansion of unreserved values.
expression = "{" [ operator ] variable-list "}"
operator = op-level2 / op-level3 / op-reserve
op-level2 = "+" / "#"
op-level3 = "." / "/" / ";" / "?" / "&"
op-reserve = "=" / "," / "!" / "@" / "|"
The operator characters have been chosen to reflect each of their roles as reserved characters in the URI generic syntax. The operators defined in Section 3 of this specification include:
-
+Reserved character strings; -
#Fragment identifiers prefixed by "#"; -
.Name labels or extensions prefixed by "."; -
/Path segments prefixed by "/"; -
;Path parameter name or name=value pairs prefixed by ";"; -
?Query component beginning with "?" and consisting of name=value pairs separated by "&"; and, -
&Continuation of query-style &name=value pairs within a literal query component.
The operator characters equals ("="), comma (","), exclamation ("!"), at sign ("@"), and pipe ("|") are reserved for future extensions.
The expression syntax specifically excludes use of the dollar ("$") and parentheses ["(" and ")"] characters so that they remain available for use outside the scope of this specification. For example, a macro language might use these characters to apply macro substitution to a string prior to that string being processed as a URI Template.
2.3. Variables
After the operator (if any), each expression contains a list of one or more comma-separated variable specifiers (varspec). The variable names serve multiple purposes: documentation for what kinds of values are expected, identifiers for associating values within a template processor, and the literal string to use for the name in name=value expansions (aside from when exploding an associative array). Variable names are case-sensitive because the name might be expanded within a case-sensitive URI component.
variable-list = varspec *( "," varspec )
varspec = varname [ modifier-level4 ]
varname = varchar *( ["."] varchar )
varchar = ALPHA / DIGIT / "_" / pct-encoded
A varname MAY contain one or more pct-encoded triplets. These triplets are considered an essential part of the variable name and are not decoded during processing. A varname containing pct-encoded characters is not the same variable as a varname with those same characters decoded. Applications that provide URI Templates are expected to be consistent in their use of pct-encoding within variable names.
An expression MAY reference variables that are unknown to the template processor or whose value is set to a special "undefined" value, such as undef or null. Such undefined variables are given special treatment by the expansion process (Section 3.2.1).
A variable value that is a string of length zero is not considered undefined; it has the defined value of an empty string.
In Level 4 templates, a variable may have a composite value in the form of a list of values or an associative array of (name, value) pairs. Such value types are not directly indicated by the template syntax, but they do have an impact on the expansion process (Section 3.2.1).
A variable defined as a list value is considered undefined if the list contains zero members. A variable defined as an associative array of (name, value) pairs is considered undefined if the array contains zero members or if all member names in the array are associated with undefined values.
2.4. Value Modifiers
Each of the variables in a Level 4 template expression can have a modifier indicating either that its expansion is limited to a prefix of the variable's value string or that its expansion is exploded as a composite value in the form of a value list or an associative array of (name, value) pairs.
modifier-level4 = prefix / explode
2.4.1. Prefix Values
A prefix modifier indicates that the variable expansion is limited to a prefix of the variable's value string. Prefix modifiers are often used to partition an identifier space hierarchically, as is common in reference indices and hash-based storage. It also serves to limit the expanded value to a maximum number of characters. Prefix modifiers are not applicable to variables that have composite values.
prefix = ":" max-length
max-length = %x31-39 0*3DIGIT ; positive integer < 10000
The max-length is a positive integer that refers to a maximum number of characters from the beginning of the variable's value as a Unicode string. Note that this numbering is in characters, not octets, in order to avoid splitting between the octets of a multi-octet-encoded character or within a pct-encoded triplet. If the max-length is greater than the length of the variable's value, then the entire value string is used.
For example,
Given the variable assignments
var := "value"
semi := ";"
Example Template Expansion
{var} value
{var:20} value
{var:3} val
{semi} %3B
{semi:2} %3B
2.4.2. Composite Values
An explode ("*") modifier indicates that the variable is to be treated as a composite value consisting of either a list of values or an associative array of (name, value) pairs. Hence, the expansion process is applied to each member of the composite as if it were listed as a separate variable. This kind of variable specification is significantly less self-documenting than non-exploded variables, since there is less correspondence between the variable name and how the URI reference appears after expansion.
explode = "*"
Since URI Templates do not contain an indication of type or schema, the type for an exploded variable is assumed to be determined by context. For example, the processor might be supplied values in a form that differentiates values as strings, lists, or associative arrays. Likewise, the context in which the template is used (script, mark-up language, Interface Definition Language, etc.) might define rules for associating variable names with types, structures, or schema.
Explode modifiers improve brevity in the URI Template syntax. For example, a resource that provides a geographic map for a given street address might accept a hundred permutations on fields for address input, including partial addresses (e.g., just the city or postal code). Such a resource could be described as a template with each and every address component listed in order, or with a far more simple template that makes use of an explode modifier, as in
/mapper{?address*}
along with some context that defines what the variable named "address" can include, such as by reference to some other standard for addressing (e.g., [UPU-S42]). A recipient aware of the schema can then provide appropriate expansions, such as:
/mapper?city=Newport%20Beach&state=CA
The expansion process for exploded variables is dependent on both the operator being used and whether the composite value is to be treated as a list of values or as an associative array of (name, value) pairs. Structures are processed as if they are an associative array with names corresponding to the fields in the structure definition and "." separators used to indicate name hierarchy in substructures.
If a variable has a composite structure and only some of the fields in that structure have defined values, then only the defined pairs are present in the expansion. This can be useful for templates that consist of a large number of potential query terms.
An explode modifier applied to a list variable causes the expansion to iterate over the list's member values. For path and query parameter expansions, each member value is paired with the variable's name as a (varname, value) pair. This allows path and query parameters to be repeated for multiple values, as in
Given the variable assignments
year := ("1965", "2000", "2012")
dom := ("example", "com")
Example Template Expansion
find{?year*} find?year=1965&year=2000&year=2012
www{.dom*} www.example.com