Subject: [netmod] Guidance on list vs. container of list

From: Christian Hopps <[email-masked]>
Date: Mon, 14 Dec 2015 20:56:00 -0500

Some models seem to place a single list of things inside a 
container also named after the items in the list, e.g.,
 
+--ro modulename
   +--rw ribs
      +--rw rib* [name] 
         +--rw name 
 
I don't see the purpose of these containers. It seems to me that 
one can model and query the exact same data without the outer 
container. That is,
 
+--ro modulename
   +--rw rib* [name] 
      +--rw name 

Is there something useful about these containers that I've missed, 
as it's a fairly common pattern in the models I've been looking 
at.   Example comparisons below.. 

Thanks,
Chris.

w/ container: 
 
    <modulename> 
      <ribs> 
        <rib> 
          <name>foo</name> 
        </rib> <rib> 
          <name>bar</name> 
        </rib> ... 
      </ribs> 
    </modulename> 

w/o container: 
 
    <modulename>
      <rib> 
        <name>foo</name> 
      </rib> <rib> 
        <name>bar</name> 
      </rib> ... 
    </modulename> 

Likewise if you want to fetch all ribs you can either way:

    <filter>
      <modulename>
        <ribs/>
      </modulename>
    </filter> 
 
or
 
    <filter>
      <modulename>
        <rib/>
      </modulename>
    </filter> 
 
Or a particular rib
 
    <filter>
      <modulename>
        <ribs> 
          <rib> 
            <name>foo</name>
          </rib> 
        </ribs>
      </modulename>
    </filter> 
 
or
 
    <filter>
      <modulename> 
        <rib> 
          <name>foo</name>
        </rib>
      </modulename>
    </filter> 

Using xpath:

    /modulename/ribs/rib[name='foo'] 

or

    /modulename/rib[name='foo']

---

From: Andy Bierman <[email-masked]>
Date: Mon, 14 Dec 2015 18:30:19 -0800

Hi,

Use of NP-containers are subjective, based on how you
want to organize your data.  The extra layer of containment
may be a waste, but it sometimes has a purpose

  - 2 or more sibling lists with lots of entries can be mixed in JSON,
    so putting each list in its container prevents that.
 - There is no standard way to 'delete-all' in NETCONF or RESTCONF
    but a 'replace' on the parent container can be used for this purpose.
    (container of list or leaf-list)
 - container servers as a conceptual 'root' for external augments

Andy

On Mon, Dec 14, 2015 at 5:56 PM, Christian Hopps <[email-masked]> wrote:

>
> Some models seem to place a single list of things inside a container also
> named after the items in the list, e.g.,
>
> +--ro modulename
>   +--rw ribs
>      +--rw rib* [name]         +--rw name
> I don't see the purpose of these containers. It seems to me that one can
> model and query the exact same data without the outer container. That is,
>
> +--ro modulename
>   +--rw rib* [name]      +--rw name
> Is there something useful about these containers that I've missed, as it's
> a fairly common pattern in the models I've been looking at.   Example
> comparisons below..
> Thanks,
> Chris.
>
>
> w/ container:
>    <modulename>      <ribs>        <rib>          <name>foo</name>
> </rib> <rib>          <name>bar</name>        </rib> ...      </ribs>
> </modulename>
> w/o container:
>    <modulename>
>      <rib>        <name>foo</name>      </rib> <rib>
> <name>bar</name>      </rib> ...    </modulename>
>        <ribs>          <rib>            <name>foo</name>
>          </rib>        </ribs>
>      </modulename>
>    </filter>
> or
>
>    <filter>
>      <modulename>        <rib>          <name>foo</name>
>        </rib>
>      </modulename>
>    </filter>
> Using xpath:
>
> _______________________________________________
> netmod mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/netmod
>
>

---

From: Anees Shaikh <[email-masked]>
Date: Mon, 14 Dec 2015 19:17:32 -0800

hi Chris, in OpenConfig models we use enclosing containers on lists based
on feedback from some implementors who claimed that it made it more
efficient to, for example, retrieve the entire list (ask for the
container), retrieve the keys in the list (ask for the list node), or
retrieve a particular element of the list (specify the key).

Aside from some stuttering in the paths (which can be a little annoying but
I don't expect to write the config instances by hand), there didn't seem to
be a major downside.  So we try to be consistent across the models with
this approach.  After getting some more experience with the
implementations, we might revisit.

thanks.
-- Anees

On Mon, Dec 14, 2015 at 6:30 PM, Andy Bierman <[email-masked]> wrote:

>> Is there something useful about these containers that I've missed, as
>> it's a fairly common pattern in the models I've been looking at.   Example
>> comparisons below..
>> Thanks,
>> Chris.
>>
>>
>> w/ container:

---

From: Ladislav Lhotka <[email-masked]>
Date: Tue, 15 Dec 2015 12:37:57 +0100

>     so putting each list in its container prevents that.

No, in JSON all list entries are always nicely packed in an array. It is
the XML encoding where entries of two lists can be interleaved.

For example, if we have

list foo { ... }
list bar { ... }

then JSON encoding is always

"foo": [...foo entries...]
"bar": [...bar entries...]

whereas in XML we can have, e.g.

<bar>...</bar>
<foo>...</foo>
<bar>...</bar>
<bar>...</bar>
<foo>...</foo>

Lada

-- 
Ladislav Lhotka, CZ.NIC Labs
PGP Key ID: E74E8C0C

---

From: Christian Hopps <[email-masked]>
Date: Wed, 16 Dec 2015 11:48:12 -0500

Anees Shaikh <[email-masked]> writes:

> hi Chris, in OpenConfig models we use enclosing containers on 
> lists based on feedback from some implementors who claimed that 
> it made it more efficient to, for example, retrieve the entire 
> list (ask for the container), retrieve the keys in the list (ask 
> for the list node), or retrieve a particular element of the list 
> (specify the key). 

But, I don't think asking for the list node returns only keys, I 
think it returns the entire content of the node, i.e., it's 
equivalent to asking for the out container if that container only 
contains a single list (the model in question here). 

Thanks,
Chris.

> Aside from some stuttering in the paths (which can be a little 
> annoying but I don't expect to write the config instances by 
> hand), there didn't seem to be a major downside.  So we try to 
> be consistent across the models with this approach.  After 
> getting some more experience with the implementations, we might 
> revisit.
>
> thanks.  -- Anees
>
>> Use of NP-containers are subjective, based on how you want to 
>> organize your data.  The extra layer of containment may be a 
>> waste, but it sometimes has a purpose
>>
>>     but a 'replace' on the parent container can be used for 
>>     this purpose.  (container of list or leaf-list) 
>> On Mon, Dec 14, 2015 at 5:56 PM, Christian Hopps 
>> <[email-masked]>
>> wrote:
>>
>>>
>>> I don't see the purpose of these containers. It seems to me 
>>> that one can model and query the exact same data without the 
>>> outer container. That is,
>>>
>>> +--ro modulename 
>>> Is there something useful about these containers that I've 
>>> missed, as it's a fairly common pattern in the models I've 
>>> been looking at.   Example comparisons below..  Thanks, Chris.
>>>
>>>
>>> w/ container: 
>>> </rib> <rib>          <name>bar</name>        </rib> ... 
>>> </ribs> </modulename> w/o container: 
>>>    <modulename> 
>>> <name>bar</name>      </rib> ...    </modulename> Likewise if 
>>> you want to fetch all ribs you can either way:
>>>
>>>    <filter> 
>>>      <modulename> 
>>>        <ribs/> 
>>>      </modulename> 
>>>    </filter> 
>>> or
>>>
>>>    <filter> 
>>>      <modulename> 
>>>        <rib/> 
>>>      </modulename> 
>>>    </filter> 
>>> Or a particular rib
>>>
>>>    <filter> 
>>>      <modulename> 
>>> _______________________________________________ netmod mailing 
>>> list [email-masked] 
>> _______________________________________________ netmod mailing 
>> list [email-masked]

---

From: Anees Shaikh <[email-masked]>
Date: Wed, 16 Dec 2015 09:00:05 -0800

I'm not suggesting this is necessarily standard behavior :-), but some
major implementations behave this way (it could be useful in some
circumstances) -- on those platforms, the enclosing container makes a
request for the whole list arguably less ambiguous.

thanks.
-- Anees

On Wed, Dec 16, 2015 at 8:48 AM, Christian Hopps <[email-masked]> wrote:

> But, I don't think asking for the list node returns only keys, I think it
> returns the entire content of the node, i.e., it's equivalent to asking for
> the out container if that container only contains a single list (the model
> in question here).
> Thanks,
> Chris.
>
>
> Aside from some stuttering in the paths (which can be a little annoying
>> but I don't expect to write the config instances by hand), there didn't
>> seem to be a major downside.  So we try to be consistent across the models
>> with this approach.  After getting some more experience with the
>>> Use of NP-containers are subjective, based on how you want to organize
>>> your data.  The extra layer of containment may be a waste, but it sometimes
>>> has a purpose
>>>
>>>   - 2 or more sibling lists with lots of entries can be mixed   in
>>> JSON,     so putting each list in its container prevents that.  - There is
>>> no standard way to 'delete-all' in NETCONF or  RESTCONF     but a 'replace'
>>> on the parent container can be used for     this purpose.  (container of
>>> list or leaf-list)  - container servers as a conceptual 'root' for
>>> external  augments
>>>
>>> Andy
>>>
>>>
>>>> Some models seem to place a single list of things inside a container
>>>> also named after the items in the list, e.g.,
>>>>
>>>> +--ro modulename   +--rw ribs      +--rw rib* [name]         +--rw name
>>>> +--ro modulename   +--rw rib* [name]      +--rw name Is there something
>>>> useful about these containers that I've missed, as it's a fairly common
>>>> pattern in the models I've been looking at.   Example comparisons below..
>>>> Thanks, Chris.
>>>>
>>>>
>>>> w/ container:    <modulename>      <ribs>        <rib>
>>>> <name>foo</name> </rib> <rib>          <name>bar</name>        </rib> ...
>>>> </ribs> </modulename> w/o container:    <modulename>      <rib>
>>>> <name>foo</name>      </rib> <rib> <name>bar</name>      </rib> ...
>>>> </modulename> Likewise if you want to fetch all ribs you can either way:
>>>>
>>>>    <filter>      <modulename>        <ribs/>      </modulename>
>>>> </filter> or
>>>>
>>>>    <filter>      <modulename>        <rib/>      </modulename>
>>>> </filter> Or a particular rib
>>>>
>>>>    <filter>      <modulename>        <ribs>          <rib>
>>>> <name>foo</name>          </rib>        </ribs>      </modulename>
>>>> </filter> or
>>>>
>>>>    <filter>      <modulename>        <rib>          <name>foo</name>
>>>>     </rib>      </modulename>    </filter> Using xpath:
>>>>
>>>>    /modulename/ribs/rib[name='foo'] or
>>>>
>>>> _______________________________________________ netmod mailing list
>>>> [email-masked] https://www.ietf.org/mailman/listinfo/netmod
>>>>
>>>>
>>>>
>>> _______________________________________________ netmod mailing list
>>> [email-masked] https://www.ietf.org/mailman/listinfo/netmod
>>>
>>>
>>>
>

---

From: Christian Hopps <[email-masked]>
Date: Wed, 16 Dec 2015 12:04:12 -0500

Andy Bierman <[email-masked]> writes:

>   JSON, 
 
Did you mean XML here (Lada indicated it's not the case with 
JSON)? I was curious if mixing like this was allowed in XML case 
(whether items from 2 different lists or even sibling leafs). I 
was hoping that once a list started in the XML all items in the 
list would be present before other items outside the list. If what 
your saying applies to XML then one would have to iterate all 
sibling nodes in the containing node to collect the list. This 
would seem to be the case even with sibling leafs in the model. I 
find this a bit surprising, and would expect bugs in 
implementation if so. :) 
 
>  - container servers as a conceptual 'root' for external 
 
This might be useful in some cases, probably not a reason to 
always include a container wrapper though. 
 
>     but a 'replace' on the parent container can be used for this 
>     purpose.  (container of list or leaf-list) 

This is an interesting use -- using a modeling technique to to get 
around missing functionality in the protocol (hello opstate! :) 

Seriously though, should we consider adding delete-all 
functionality then? 

Thanks, Chris.

> <[email-masked]> wrote:
>
>>
>> missed, as it's a fairly common pattern in the models I've been 
>> looking at.   Example comparisons below..  Thanks, Chris.
>>
>>
>> w/ container:

---

From: Martin Bjorklund <[email-masked]>
Date: Wed, 16 Dec 2015 18:08:18 +0100 (CET)

Anees Shaikh <[email-masked]> wrote:
> I'm not suggesting this is necessarily standard behavior :-)

I think this demonstrates that it is probably not a good idea to
design (standard) data models to optimize for a single protocol /
implementation.  For NETCONF, the problem is clearly in the protocol,
and it should be fixed in the protocol (Andy already showed a
solution).

Going back to the original question, I don't think there's a single
rule to be used.  Sometimes the additional container makes sense, but
in some cases (normally further down in the hierarchy, for "smaller"
lists) it just adds noise.

/martin

, but some

---

From: Andy Bierman <[email-masked]>
Date: Wed, 16 Dec 2015 09:41:56 -0800

On Wed, Dec 16, 2015 at 9:04 AM, Christian Hopps <[email-masked]> wrote:

> Did you mean XML here (Lada indicated it's not the case with JSON)? I was
> curious if mixing like this was allowed in XML case (whether items from 2
> different lists or even sibling leafs). I was hoping that once a list
> started in the XML all items in the list would be present before other
> items outside the list. If what your saying applies to XML then one would
> have to iterate all sibling nodes in the containing node to collect the
> list. This would seem to be the case even with sibling leafs in the model.
> I find this a bit surprising, and would expect bugs in implementation if
> so. :)
>

Lada is correct so ignore this use-case

> This might be useful in some cases, probably not a reason to always
> include a container wrapper though.
>
> This is an interesting use -- using a modeling technique to to get around
> missing functionality in the protocol (hello opstate! :)
> Seriously though, should we consider adding delete-all functionality then?
>

Maybe in the future if NETCONF gets updated

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Thu, 17 Dec 2015 06:59:34 +0100

> On 16 Dec 2015, at 18:08, Martin Bjorklund <[email-masked]> wrote:
> 

Agreed. This deficiency also blocks the introduction of keyless config lists that several people requested.

> lists) it just adds noise.

Also, it is usually a good idea to use a wrapper container for user-ordered lists.

Lada

---

From: Ladislav Lhotka <[email-masked]>
Date: Thu, 17 Dec 2015 07:09:00 +0100

> On 16 Dec 2015, at 18:04, Christian Hopps <[email-masked]> wrote:
> 
> 
>> Use of NP-containers are subjective, based on how you want to organize your data.  The extra layer of containment may be a waste, but it sometimes has a purpose
>> 
>>  - 2 or more sibling lists with lots of entries can be mixed in   JSON,     so putting each list in its container prevents that.
> Did you mean XML here (Lada indicated it's not the case with JSON)? I was curious if mixing like this was allowed in XML case (whether items from 2 different lists or even sibling leafs). I was hoping that once a list started in the XML all items in the list would be present before other items outside the list. If what your saying applies to XML then one would have to iterate all sibling nodes in

The possibility of (leaf-)list entries being interleaved with other sibling XML elements is explicitly mentioned in RFC 6020 (sec. 7.7.6 and 7.8.5). This shouldn't come as a surprise because XML has no notion of lists.

>  the containing node to collect the list. This would seem to be the case even with sibling leafs in the model. I find this a bit surprising, and would expect bugs in implementation if so. :)
> This might be useful in some cases, probably not a reason to always include a container wrapper though.
>> - There is no standard way to 'delete-all' in NETCONF or  RESTCONF     but a 'replace' on the parent container can be used for this     purpose.  (container of list or leaf-list)
> 
> This is an interesting use -- using a modeling technique to to get around missing functionality in the protocol (hello opstate! :)

Absolutely.

Lada

>>> Some models seem to place a single list of things inside a container also named after the items in the list, e.g.,
>>> 
>>> +--ro modulename   +--rw ribs      +--rw rib* [name]         +--rw name I don't see the purpose of these containers. It seems to me that one can model and query the exact same data without the outer container. That is,
>>> 
>>> +--ro modulename   +--rw rib* [name]      +--rw name Is there something useful about these containers that I've missed, as it's a fairly common pattern in the models I've been looking at.   Example comparisons below..  Thanks, Chris.
>>> 
>>> 
>>> w/ container:    <modulename>      <ribs>        <rib>    <name>foo</name> </rib> <rib>          <name>bar</name>        </rib> ... </ribs> </modulename> w/o container:    <modulename>      <rib>        <name>foo</name>      </rib> <rib> <name>bar</name>      </rib> ...    </modulename> Likewise if you want to fetch all ribs you can either way:
>>> 
>>>   <filter>      <modulename>        <ribs/>      </modulename>    </filter> or
>>> 
>>>   <filter>      <modulename>        <rib/>      </modulename>    </filter> Or a particular rib
>>> 
>>>   <filter>      <modulename>        <ribs>          <rib>            <name>foo</name>          </rib>        </ribs>      </modulename>    </filter> or
>>> 
>>>   <filter>      <modulename>        <rib>          <name>foo</name>        </rib>      </modulename>    </filter> Using xpath:
>>> 
>>> _______________________________________________ netmod mailing list [email-masked] https://www.ietf.org/mailman/listinfo/netmod
>>> 
>>> 
>