skip to content

In a RESTCONF URI, how are multi-key list entries, key values containing reserved characters, and leaf-list entries encoded?

level: middleimportance: should knowfreq 9%

answer

  1. one path segment per entry
  2. order comes from the key statement
  3. commas between keys, never slashes
  4. canonical form, then percent-encode

basics

~20 s

A list entry is one segment: the list name, '=', then every key value in key-statement order separated by commas; a leaf-list entry is name=value. Values use their type's canonical form, with reserved characters, commas included, percent-encoded.

solid answer

~40 s

RFC 8040 §3.5.3 puts a list entry in one path segment: the list name, `=`, then the value of each key leaf in the order the YANG `key` statement lists them, separated by commas. Every key must be present, since partial instance identifiers are not supported, and two commas in a row mean an empty-string key, not a missing one. Each value is written in the canonical form of its YANG type and reserved characters are percent-encoded; a comma inside a value must become `%2C` so it cannot be read as a separator. A leaf-list entry is `name=value` under the same rules, with a comma encoded even though a leaf-list entry has only one value. For a list `neighbor` keyed by `vrf address`, the entry for vrf `blue` and address `2001:db8::1` is `neighbor=blue,2001%3Adb8%3A%3A1`.

code

yang · 9 lines
yang
container peering {
  list neighbor {
    key "vrf address";
    leaf vrf { type string; }
    leaf address { type inet:ipv6-address; }
    leaf description { type string; }
  }
  leaf-list allowed-asn { type uint32; }
}

go deeper

for a junior

Remember that a list entry is name=key in one segment and that several keys are joined by commas.

for a middle

Explain key order from the key statement, the all-keys rule, the empty-string meaning of two commas, and why a comma inside a value becomes %2C.

for a senior

Catch canonical-form bugs in automation, uppercase or uncompressed IPv6 and leading zeros, and prefer building URIs from key values the server itself reported.

for a principal

Consider how key design in a model, composite keys or free-text keys, shapes how easily every client can address entries over RESTCONF.

## The example model To keep the rules concrete, take an illustrative module named `example-peering`; the `example-` prefix marks it as documentation, as RFC 8040's own examples do. It has a top-level container `peering`, a list `neighbor` keyed by two leaves, `vrf` (a string) and `address` (an `inet:ipv6-address` from `ietf-inet-types`, RFC 9911, which obsoletes RFC 6991), and a leaf-list `allowed-asn` of type `uint32`. The fragment is in the code example. ## Lists with more than one key RFC 8040 §3.5.3 fixes how a list entry appears in a URI: 1. The entry occupies **one path segment**. 2. The segment starts with the list name and an `=`. 3. The value of each key leaf follows **in the order of the YANG `key` statement**, which is the rule even when the leaves are declared in another order. 4. Every value except the last is followed by a comma. So the entry for vrf `blue`, address `2001:db8::1` is `/restconf/data/example-peering:peering/neighbor=blue,2001%3Adb8%3A%3A1`. Reversing the order would ask for an entry whose vrf is `2001:db8::1` and whose address is `blue`. Two more rules are easy to miss: - **Every key component must be present.** RFC 8040 says partial instance identifiers are not supported, so `neighbor=blue` does not mean every neighbor in vrf `blue`. To see those, retrieve the `peering` container, or the list itself in JSON, and select on the client. - **Consecutive commas are an empty string.** Missing key values are not allowed, so in RFC 8040's example `list1=foo,,baz` is an entry with three keys whose second key is the zero-length string. ## Canonical form, then percent-encoding Each key value is written as a string in the **canonical representation** of its YANG type, and then every reserved character in it is percent-encoded (RFC 8040 cites RFC 3986 §2.1 and §2.5 for this). RFC 7950 says values in the data tree are conceptually stored in canonical form, which is why the canonical spelling is the one that names an entry. | Value as someone typed it | Canonical form | In the URI | |---|---|---| | IPv6 `2001:DB8:0:0:0:0:0:1` | `2001:db8::1` (RFC 5952 text form, which ietf-inet-types makes canonical) | `2001%3Adb8%3A%3A1` | | `uint32` written `064496` | `64496` (YANG's canonical integer has no leading zeros) | `64496` | | a string key `red,blue` | `red,blue` | `red%2Cblue` | | a string key `eth0/1` | `eth0/1` | `eth0%2F1` | RFC 8040's worked example encodes a key containing a comma, a single quote, a colon, a space and a slash as `%2C%27"%3A"%20%2F`, and remarks that the double quote is not reserved. The comma deserves the most attention: RFC 8040 states that it MUST be percent-encoded when it occurs in a key value, because it is the separator between keys. ## Leaf-list entries A leaf-list entry is also one segment: the leaf-list name, `=`, and the value, under the same canonical-form and percent-encoding rules. With 64496 taken from the documentation ASN range of RFC 5398, the entry is `.../example-peering:peering/allowed-asn=64496`. Two leaf-list details from §3.5.3: - A comma in a leaf-list value is percent-encoded too, even though a leaf-list entry carries only one value; the RFC chose one consistent rule over a special case. - YANG 1.1 allows duplicate values in a non-configuration leaf-list, and then there is no way to name one particular instance. ## Encoding a list entry, step by step 1. Read the list's `key` statement and take its leaves in that order. 2. Write each value in the canonical form of its type: lowercase compressed IPv6, integers without leading zeros or a plus sign, and booleans as `true` or `false`, which for a boolean is simply its lexical form. 3. Percent-encode every reserved character inside each value, the comma included. 4. Join the encoded values with literal commas. 5. Put the list name and `=` in front, and use the result as one path segment. The same procedure with one value is the leaf-list rule. ## Common errors - Writing each key as its own segment, as in `neighbor/blue/...`. - Using XPath predicate syntax, `neighbor[vrf='blue']`, which is how XPath and the `instance-identifier` type select an entry, not how a RESTCONF path does. - Taking key order from the alphabet or from the order of the leaf statements instead of the `key` statement. - Sending an uppercase or uncompressed IPv6 address, or an integer with leading zeros. - Forgetting that a comma inside a value must become `%2C`.

  • In RESTCONF, can the segment neighbor=blue return every neighbor in vrf blue?
    No. RFC 8040 requires every component of the `key` statement and does not support partial instance identifiers, so a segment with fewer values than the key names is not a valid entry address. To find all neighbors in one vrf, retrieve the `peering` container, or the `neighbor` list in JSON, and select the entries on the client.
  • Why does RFC 8040 percent-encode a comma in a leaf-list value, where no separator is possible?
    For consistency. A leaf-list entry carries exactly one value, so a raw comma could not be mistaken for a key separator, but RFC 8040 encodes it anyway so that list keys and leaf-list values follow one rule and a parser needs no special case.
  • Why must the IPv6 key be sent as 2001:db8::1 rather than 2001:DB8::1?
    RFC 8040 requires key values in the canonical representation of their YANG type, and ietf-inet-types defines canonical IPv6 as the RFC 5952 text form, lowercase and compressed. A client sending another spelling is outside the specification and cannot rely on the server matching the entry.

saying these in an interview costs you the question

  • Multiple keys go in separate path segments, one per key.
  • Key order in the URI follows the order the key leaves are declared.
  • neighbor=blue matches every entry whose first key is blue.
  • Two commas in a row mean a key value was left out.
  • A comma inside a key value can stay raw in the URI.
  • Any spelling of an IPv6 address works as a key value.