Re: [Netconf] Fwd: I-D Action: draft-bierman-netconf-restconf-03.txt

Martin Bjorklund <mbj@tail-f.com> Sat, 11 January 2014 12:09 UTC

Return-Path: <mbj@tail-f.com>
X-Original-To: netconf@ietfa.amsl.com
Delivered-To: netconf@ietfa.amsl.com
Received: from localhost (ietfa.amsl.com [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id B71E71ADF9F for <netconf@ietfa.amsl.com>; Sat, 11 Jan 2014 04:09:49 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.438
X-Spam-Level:
X-Spam-Status: No, score=-2.438 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RP_MATCHES_RCVD=-0.538] autolearn=ham
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qqWBn3oHfvDk for <netconf@ietfa.amsl.com>; Sat, 11 Jan 2014 04:09:47 -0800 (PST)
Received: from mail.tail-f.com (mail.tail-f.com [109.74.15.94]) by ietfa.amsl.com (Postfix) with ESMTP id 9D4721ACC82 for <netconf@ietf.org>; Sat, 11 Jan 2014 04:09:46 -0800 (PST)
Received: from localhost (unknown [193.12.32.88]) by mail.tail-f.com (Postfix) with ESMTPSA id B9A1A240C187; Sat, 11 Jan 2014 13:09:35 +0100 (CET)
Date: Sat, 11 Jan 2014 13:09:35 +0100
Message-Id: <20140111.130935.29100484.mbj@tail-f.com>
To: wdec.ietf@gmail.com
From: Martin Bjorklund <mbj@tail-f.com>
In-Reply-To: <CAFFjW4hcnAWAMt4kPd+4XC04gzXVYn+_5NwtcnhG4OzVse5nmw@mail.gmail.com>
References: <CAFFjW4ht0WTBEqzYvrHTGaTi=y_Bx7NBoYRXnNh2p+y6AEvmuA@mail.gmail.com> <20140110.194818.364466126.mbj@tail-f.com> <CAFFjW4hcnAWAMt4kPd+4XC04gzXVYn+_5NwtcnhG4OzVse5nmw@mail.gmail.com>
X-Mailer: Mew version 6.5rc2 on Emacs 23.4 / Mule 6.0 (HANACHIRUSATO)
Mime-Version: 1.0
Content-Type: Text/Plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Cc: netconf@ietf.org
Subject: Re: [Netconf] Fwd: I-D Action: draft-bierman-netconf-restconf-03.txt
X-BeenThere: netconf@ietf.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Network Configuration WG mailing list <netconf.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/netconf>, <mailto:netconf-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/netconf/>
List-Post: <mailto:netconf@ietf.org>
List-Help: <mailto:netconf-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/netconf>, <mailto:netconf-request@ietf.org?subject=subscribe>
X-List-Received-Date: Sat, 11 Jan 2014 12:09:49 -0000

Wojciech Dec <wdec.ietf@gmail.com> wrote:
> On 10 January 2014 19:48, Martin Bjorklund <mbj@tail-f.com> wrote:
> > Wojciech Dec <wdec.ietf@gmail.com> wrote:
> >> Hi Martin,
> >>
> >> On 10 January 2014 16:25, Martin Bjorklund <mbj@tail-f.com> wrote:
> >> > Wojciech Dec <wdec.ietf@gmail.com> wrote:
> >> >> Hi Martin,
> >> >>
> >> >> On 8 January 2014 12:29, Martin Bjorklund <mbj@tail-f.com> wrote:
> >> >> > Wojciech Dec <wdec.ietf@gmail.com> wrote:
> >> >> >> On 6 January 2014 12:49, Andy Bierman <andy@yumaworks.com> wrote:
> >> >> >> >
> >> >> >> >
> >> >> >> >
> >> >> >> > On Mon, Jan 6, 2014 at 3:33 AM, Wojciech Dec <wdec.ietf@gmail.com>
> >> >> >> > wrote:
> >> >> >> >>
> >> >> >> >> Hi Andy, all,
> >> >> >> >>
> >> >> >> >> are the issues leading to this draft documented somewhere? The IETF
> >> >> >> >> 88 minutes only talk about the yang patch aspect.
> >> >> >> >>
> >> >> >> >> Anyway, I took a read through the latest document and the change to
> >> >> >> >> have all Yang data-nodes be resources. Am I correct in interpreting
> >> >> >> >> it
> >> >> >> >> that now  every leaf node  effectively becomes a resource with a
> >> >> >> >> separate URI? Could the authors provide some more insight regarding
> >> >> >> >> this change?
> >> >> >> >>
> >> >> >> >
> >> >> >> >
> >> >> >> >
> >> >> >> > Since YANG Patch is now optional, there is no way to delete an
> >> >> >> > optional
> >> >> >> > leaf
> >> >> >> > or leaf-list otherwise, except to copy the entire resource, and then
> >> >> >> > replace
> >> >> >> > the entire resource (minus the optional leaf).
> >> >> >>
> >> >> >>
> >> >> >> I am still not able to get the full rationale for the change.  Can the
> >> >> >> authors or chairs provide that?
> >> >> >>
> >> >> >> Anyway, it now appears that every single data leaf is a resource,
> >> >> >> instead of an attribute
> >> >> >
> >> >> > Yes, every leaf is a subresource to its parent list or container.
> >> >> > This just means that you can GET/POST/DELETE the leaf directly, w/o
> >> >> > having to PATCH the parent.
> >> >> >
> >> >> >> and the spec doesn't specify a distinction
> >> >> >> between handling parent resources and its sub-resources, e.g. At the
> >> >> >> very least POST/PUT operations to sub resources need to be constrained
> >> >> >> by their parent resource, and leaving that up to the implementation is
> >> >> >> kind of a step backwards for the spec as a whole besides being IMO a
> >> >> >> major complication for client or server, and likely both e.g how
> >> >> >> should a change to a sub-resource that doesn't meet some condition of
> >> >> >> the parent be handled? For a single parent resource, how should
> >> >> >> multiple sub-resource changes be coordinated (the parent resource
> >> >> >> needs to be consistent)? Etc.
> >> >> >
> >> >> > I am afraid I do not understand your concern.  Could you provide an
> >> >> > example (data model and requests) that you feel is problematic or
> >> >> > unclear?
> >> >>
> >> >>
> >> >> A simple example:
> >> >>
> >> >>     container book {
> >> >>
> >> >>                 leaf price {
> >> >>                      type string;
> >> >>                  }
> >> >>                 leaf tax-amount {
> >> >>                      type string;
> >> >>                  }
> >> >>
> >> >>      }
> >> >>
> >> >> Price and taxt are typically related.
> >> >> A (better) REST API design would seek to minimize transactional
> >> >> effects to the client while protecting the consistency/sanity of the
> >> >> data: To update the resource, a POST operation to foo/book would carry
> >> >> in the envelope both a new price and the tax amount. A (worse) REST
> >> >> API design would expose both price and tax-amount as separate
> >> >> resources, accept POST to both foo/book/price and foo/book/tax-amount
> >> >> and hope-for-the-best that the client succeeds and all. Several non
> >> >> trivial failuire scenarios come up here too.
> >> >
> >> > Note that with the current design, you get both, and the client can
> >> > choose to use the resource that fits his needs best.  Specifically,
> >> > book is still a resource, so if the client wants to update both leafs
> >> > in one transaction, it would POST to the book resource.
> >>
> >> Well, ok, but how can the server assume what he client chooses to do,
> >> other than supporting every possibility. Or alternatively, how can we
> >> tell the client: "Although RESTCONF spec + YANG model might indicate
> >> otherwise, leafs are not resources in our implementation"?
> >
> > The server still has to support the relevant operations on the leaf
> > resources, but the client can choose to not use them if it wants to.
> >
> > See also below.
> >
> >
> >> >> The key is that REST API design is very much about determining what is
> >> >> a resource,  its representation by a URI, and what are the attributes
> >> >> of a resource. In draft -03, everything is now a resource, and
> >> >> everything is also attribute. This IMO ultimately complicates and
> >> >> bloats code (on client, server, and likely both)
> >> >
> >> > In our server we actually had special code to handle the case that
> >> > leafs were not resources.  So in our case the code is now simpler.
> >> >
> >> > On the client side I do not know.  But again note that the client can
> >> > choose to treat all leafs as attributes if it wants to.
> >> >
> >> >> and will lead to
> >> >> brittle API and poor user experience.
> >> >>
> >> >> Another quick example:
> >> >>
> >> >>
> >> >>     container book {
> >> >>
> >> >>                 list page {
> >> >>                     key page-nr;
> >> >>                     leaf page-nr {type string;}
> >> >>                     leaf text {type string;}
> >> >>                  }
> >> >>      }
> >> >>
> >> >> The RESTConf URI for the above would <root stuff
> >> >> here>/book/page/{page-nr}/text
> >> >>
> >> >> In general with REST APIs it is important that we do NOT expose the
> >> >> dependent sub-resources directly thus allowing someone to create (POST
> >> >> or PUT) to <root stuff here>/book/page/{page-nr}  without a book, or
> >> >> text without a page, or other cases that do not make sense
> >> >
> >> > Without a book doesn't work since a page is defined under the book.
> >> > In general, such constraints should be expressed in the data model
> >> > (with proper containment and/or must / unique / mandatory etc
> >> > constraints).  This separates the semantic correctness of the instance
> >> > data from the specific API details used to change the underyling
> >> > data.  This is especially true of we want to support multiple
> >> > protocols (which is what we're doing with RESTCONF).
> >>
> >> Yeah, but how would one do that...
> >>
> >> >
> >> >> , and in
> >> >> general requiring a feast of error cases.
> >> >> Requiring the text POST/PUT  handler to also do book creation,
> >> >> validation, etc, is not a great design.
> >> >
> >> > Agreed, but that is not the intention.
> >>
> >> ... without ending up with the above, or assuming a very very specific
> >> data store ? Or perhaps, that's the thing I'm not understanding: what
> >> is the responsibility of RESTconf layer and what is the responsibility
> >> of the data store in terms of the yang schema?
> >
> > If the server gets a request from a client to set the title of a book:
> >
> >   PUT /.../book/{book-name}/page/{page-nr}/text
> >
> > and the book doesn't exist, the server signal an error.  It will not
> > automatically create the book.
> 
> Sure, I know that this should happen, but what is the responsibility
> of RESTconf layer and what is the responsibility
> of the data store in terms of the yang schema?
> Currently it appears that Restconf assumes that the whole resource
> containment (model enforcement) is assumed to be done by the data
> store.

This is up to the implementation.  In a multi-protocol implementation
one might think that the underlying datastore takes care of the "model
enforcement", but nothing prevents you from doing everything in the
RESTCONF layer.


/martin