[Netconf] RESTCONF Resource Model (was Re: Fwd: I-D Action: draft-bierman-netconf-restconf-03.txt)

Andy Bierman <andy@yumaworks.com> Fri, 10 January 2014 18:03 UTC

Return-Path: <andy@yumaworks.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 DF9AC1AE11F for <netconf@ietfa.amsl.com>; Fri, 10 Jan 2014 10:03:47 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.978
X-Spam-Level:
X-Spam-Status: No, score=-1.978 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001] 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 hVr2oBKrI9Ke for <netconf@ietfa.amsl.com>; Fri, 10 Jan 2014 10:03:44 -0800 (PST)
Received: from mail-qa0-f50.google.com (mail-qa0-f50.google.com [209.85.216.50]) by ietfa.amsl.com (Postfix) with ESMTP id E85CC1AE0D4 for <netconf@ietf.org>; Fri, 10 Jan 2014 10:03:43 -0800 (PST)
Received: by mail-qa0-f50.google.com with SMTP id cm18so3034476qab.37 for <netconf@ietf.org>; Fri, 10 Jan 2014 10:03:33 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to:cc :content-type; bh=HESEYanzxKYV4sk1VAOZgiXCAhoyE1YHEf14COEOrtk=; b=UNjaCZCM95NrMR/XxiVmmLcqRMilpVLxcmqvsUu9aQrFNgYohQhlWPfqgfz6m2MK2E BLfbbabEItYpSonBMjw4o5i3cvc4mjExBzi8HXzcZ2OGZ7fR/P8yxleig+W4Rnnkc+6W dp0DPh5LfTxehWx17NPwy+XLjQJP1tD9AI+Jye4Gxt/TPPeANNYQAYYwafuG9JfmrPHx LSoW0IazncYWYMxO5s+G/MbtYpZI5f2xT7zoOuAfOnfvpsDMAM5kp/GPNd6ethEoNWFG nVSWFNIx2HhtI0lWrNJGGrsNXtsmbTDHb3cfpgtmDLNLnKjw9JPgnLU83CqvH6OZSfoK d5Rg==
X-Gm-Message-State: ALoCoQmm1+/89wetFboRDXmR7MflTlcBRzDlliC0QGcpfl+idrODT2tg8f2A0Xif/7hiy3RlzqBA
MIME-Version: 1.0
X-Received: by 10.224.123.15 with SMTP id n15mr9895147qar.78.1389377013479; Fri, 10 Jan 2014 10:03:33 -0800 (PST)
Received: by 10.140.48.75 with HTTP; Fri, 10 Jan 2014 10:03:33 -0800 (PST)
Date: Fri, 10 Jan 2014 10:03:33 -0800
Message-ID: <CABCOCHT46nn3mqZ9kty5nBrCZPer+ERUEyR5dx-pNMsanauQaw@mail.gmail.com>
From: Andy Bierman <andy@yumaworks.com>
To: Wojciech Dec <wdec.ietf@gmail.com>
Content-Type: multipart/alternative; boundary="089e0149cf8059210704efa18b4b"
Cc: Netconf <netconf@ietf.org>
Subject: [Netconf] RESTCONF Resource Model (was Re: 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: Fri, 10 Jan 2014 18:03:48 -0000

Hi,

The resource management model is a fairly important part of
the RESTCONF architecture.  Perhaps all attempts so far have
been too simplistic.

The YANG node type seems to be irrelevant to answering
the question "what is a sub-resource?"  The set of mandatory[1]
descendant nodes are not sub-resources of a given parent.
They must exist and cannot be created and deleted
independently of the parent resource. So a sub-resource
is really any descendant sub-tree that can be created and
deleted independent of the parent resource.

IMO there should not be a complex set of rules for restricting URIs
and HTTP methods, based on mandatory vs. optional nodes.
This is a conceptual distinction which does not need to be
enforced somehow in the protocol.

It seems arbitrary to say that a resource target URI can point
at a container/list but not a leaf/leaf-list.  The server is going
to use the YANG validation rules to determine if an operation
is allowed.  DELETE will fail for a mandatory container, same
as a leaf.

[1] mandatory can be complex:
   static: mandatory, min-elements
   dynamic: if-feature, when + <static>


Andy


On Fri, Jan 10, 2014 at 7:13 AM, Wojciech Dec <wdec.ietf@gmail.com> wrote:

> On 10 January 2014 14:39, Wojciech Dec <wdec.ietf@gmail.com> wrote:
> > On 10 January 2014 11:37, Andy Bierman <andy@yumaworks.com> wrote:
> >>
> >>
> >>
> >> On Fri, Jan 10, 2014 at 1:37 AM, 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.
> >>>
> >>> 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), 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, 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. It complicates code and
> >>> creates ugly code dependencies, should the model change, etc.
> >>>
> >>>
> >>> >
> >>> >> If this current development was driven by questions/problems in the
> >>> >> support of HTTP Patch operation (incl. JSON patch), the solution
> >>> >> appears to be possibly worse than the supposed problem. That's why
> it
> >>> >> would be good to understand the rationale some more.
> >>> >
> >>> > If the "yang patch" media type is opitonal, there is no other way to
> >>> > delete optional leafs.  If the optional leaf is a resource it can be
> >>> > removed with DELETE.
> >>>
> >>> Yes, but the current "solution" is IMO a lot worse than a) mandating
> >>> PATCH, and I mean plain JSON/XML PATCH  or b) handling (specifying in
> >>> the draft how-to do) updates via POST. Thus bringing in back the
> >>> simple patch would be a good move. And the Yang patch is something
> >>> that can go into another spec, I agree.
> >>>
> >>
> >>
> >> Plain PATCH does not allow an optional leaf to be deleted.
> >> JSON patch does not work well with named data like YANG.
> >> Ignoring YANG naming and using integer indices that renumber
> >> every time a list is changed is a non-starter.  The only way to
> >> delete an optional leaf is to GET the entire parent resource,
> >> edit it offline (remove the leaf) and PUT the parent resource.
> >> This is operationally disruptive and expensive to implement
> >> in the server.  Optional leafs make up most configuration data,
> >> so a CM solution that doesn't work well for optional leafs is a bad
> idea.
> >
> > I should have been clearer: Media Type discussion aside, I meant JSON
> > patch as in "json patch for json reresented yang data", ie likely a
> > subset of pure 'application/json-patch+json', with yang-patch being in
> > some other doc. . The fact that JSON patch does not work for xml is,
> > for me at least, not an issue. A simple answer can thus be that the
> > patch is for json only.
> > In general, I don't quite follow why you say that json patch doesn't
> > allow for leaf deletion; the "remove" op seems to be pretty much
> > intended for that. Gee, the json (yang) patch could even be just
> > limited to just this task.
> >
> > That said, a solution to the " how to delete an optional leaf" problem
> > that ends up treating every data item in the system to a resource,
> > with no way for the designer to override, appears also as a bad idea.
> > Given that we have a full API spec here, even adding a custom
> > parameterized operation to the URI may be a better solution. Also,
> > evidence from the REST API world out there also indicates that for
> > better or worse, GET and PUT do actually work at scale. I would still
> > see this still as easier to deal with and implement than having every
> > single (sub-resource) data item as a resource....
> >
> > So, in summary, "conservative" options, all leading to getting the
> > spec back from resource extremes as I see can be:
> > 1. Stay with GET and PUT (I suspect that this is what will get most use
> anyway).
> > 2. Introduce JSON patching, in the form of say
> > "application/yang-json-patch" to the spec (happy to work up some text)
> > 3. Get back the "full" yang patch from draft -02
> > 4. Introduce a new action/operation invoked via a parameter.
>
> Forgot to add one more:
> 5. Introduce meta-data to handle the partial update.
>
> >
> > Thoughts?
> >
> > Cheers.
> >>
> >>
> >>>
> >>> Cheers,
> >>> Wojciech.
> >>
> >>
> >>
> >> Andy
> >>
> >>>
> >>> >
> >>> > /martin
> >>
> >>
>