<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0in;
        margin-right:0in;
        margin-bottom:0in;
        margin-left:.5in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1830173156;
        mso-list-type:hybrid;
        mso-list-template-ids:-1944053616 -1329815406 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l0:level1
        {mso-level-start-at:2;
        mso-level-number-format:bullet;
        mso-level-text:-;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:27.0pt;
        text-indent:-.25in;
        font-family:"Calibri","sans-serif";
        mso-fareast-font-family:Calibri;
        mso-bidi-font-family:"Times New Roman";}
@list l0:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:63.0pt;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l0:level3
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:99.0pt;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l0:level4
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:135.0pt;
        text-indent:-.25in;
        font-family:Symbol;}
@list l0:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:171.0pt;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l0:level6
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:207.0pt;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l0:level7
        {mso-level-number-format:bullet;
        mso-level-text:\F0B7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:243.0pt;
        text-indent:-.25in;
        font-family:Symbol;}
@list l0:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:279.0pt;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l0:level9
        {mso-level-number-format:bullet;
        mso-level-text:\F0A7;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        margin-left:315.0pt;
        text-indent:-.25in;
        font-family:Wingdings;}
ol
        {margin-bottom:0in;}
ul
        {margin-bottom:0in;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">It seems like there’s some reasonable support for going in the direction of HATEOS-esque links for defining capabilities… I suppose it’d be nice to see one
 of the more extreme examples taken to its logical conclusion. Could someone more familiar with the breadth of Nova’s extensions write out what it would look like if you actually provided links for every action reasonably available on a server?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoListParagraph" style="margin-left:27.0pt;text-indent:-.25in;mso-list:l0 level1 lfo1">
<![if !supportLists]><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><span style="mso-list:Ignore">-<span style="font:7.0pt "Times New Roman"">         
</span></span></span><![endif]><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Gabriel<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> Dolph Mathews [mailto:dolph.mathews@gmail.com]
<br>
<b>Sent:</b> Monday, May 13, 2013 9:26 AM<br>
<b>To:</b> OpenStack Development Mailing List<br>
<b>Subject:</b> Re: [openstack-dev] [openstack-tc] Proposal for API version discovery<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Thu, May 9, 2013 at 8:40 AM, Mark Washenberger <<a href="mailto:mark.washenberger@markwash.net" target="_blank">mark.washenberger@markwash.net</a>> wrote:<o:p></o:p></p>
<div>
<p class="MsoNormal">I'm not sure that is really 100% of the problem here, but we are definitely doing links in an inefficient way these days, due to an early misconception some of us on the Nova team had about *how* to do hyperlinks in json.<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Json schema [1] <span style="color:black">provides ways to indicate, _in the schema of an object_, how it is linked to other objects. For example, if I had an object</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">GET /widgets/foo</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">{</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">  'name': 'foo',</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">  'self': '/widgets/foo',</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">  'bar': '/widgets/foobar',</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">}</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">I might use a schema to communicate that 'self' is a self link, and that 'bar' is a related resource by publishing a schema</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">GET /schemas/object</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">{</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">   'type': 'object',</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">   'properties': {</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">      'name': {'type': 'string'},</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">      'self': {'type': 'string'},</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">      'bar': {'type': 'string'},</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">   },</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">   'links': [</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">      {'rel': 'self', 'href': '{self}'},</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">      {'rel': 'related', 'href': '{bar}'}</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">   ]</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">}</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">What this schema says is that name, self, and bar are string types, that you can construct a self link using the value of the "self" property, and that you can construct a related link using the value of the "bar"
 property.</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">For some reason I cannot remember, we neglected to realize that link descriptor objects [2] were only intended for json schema objects, not the regular objects described by the schemas. In the process, we made
 hyperlinks in our apis really inefficient by loading them up with unnecessary 'rels' and 'hrefs'. We also made finding relevant links difficult by requiring clients to iterate through an array rather than just explicitly looking up the relevant properties.</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">Glance v2 api fixes this problem. But we also tried to go all-in on being schema driven. This combined approach is fine for Glance, but I'm not sure that the "schema-driven" part is necessarily that useful for
 others. In any case, we needn't have such bloated json hyperlinks for future openstack apis. For example, if you want to have actions listed for a server, you could just do</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">{</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">  "id": "abcd",</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">  ...</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">  "actions": {</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">    "stop": "/servers/abcd/stop",</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">    "snapshot": "/servers/abcd/snapshot"</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">  }</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">}</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">+1; identity api v3 addresses this as well, but uses a "links" container to avoid namespace pollution.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">  {<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">    "entity": {<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">      "id": string,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">      "name": string<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">      "links": {<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">        "self": url,<o:p></o:p></p>
</div>
<p class="MsoNormal">        "related_collection": url<o:p></o:p></p>
<div>
<p class="MsoNormal">      }<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">    }<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  }<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><a href="https://github.com/openstack/identity-api/blob/master/openstack-identity-api/src/markdown/identity-api-v3.md#create-an-entity">https://github.com/openstack/identity-api/blob/master/openstack-identity-api/src/markdown/identity-api-v3.md#create-an-entity</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal"><span style="color:black">which is a bit more compressed.</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">[1] - <a href="http://tools.ietf.org/html/draft-zyp-json-schema-03" target="_blank">http://tools.ietf.org/html/draft-zyp-json-schema-03</a></span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="color:black">[2] - <a href="http://tools.ietf.org/html/draft-zyp-json-schema-03#section-6.1" target="_blank">http://tools.ietf.org/html/draft-zyp-json-schema-03#section-6.1</a></span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Wed, May 8, 2013 at 10:33 PM, Mark McLoughlin <<a href="mailto:markmc@redhat.com" target="_blank">markmc@redhat.com</a>> wrote:<o:p></o:p></p>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt">On Wed, 2013-05-08 at 18:59 +0000, Gabriel Hurley wrote:<br>
> > -----Original Message-----<br>
> > From: Vishvananda Ishaya [mailto:<a href="mailto:vishvananda@gmail.com" target="_blank">vishvananda@gmail.com</a>]<br>
> > Sent: Tuesday, May 07, 2013 3:44 PM<br>
><br>
> > It is relatively easy to include the info at servers/<uuid> however:<br>
> > {<br>
> >  "features": ["OS-EXT-SRV-ATTR", "os-start-stop"],<br>
> >  "server": {<br>
> >    "OS-EXT-SRV-ATTR:host": "1169a68456af48238da47b1d5957a714",<br>
> >    "OS-EXT-SRV-ATTR:hypervisor_hostname": "fake-mini",<br>
> >    "OS-EXT-SRV-ATTR:instance_name": "instance-00000001",<br>
> >    "links": [<br>
> >      {"rel": "self",<br>
> >       "href":"<a href="http://example.org/v3/servers/009e9aca-b765-11e2-855a-" target="_blank">http://example.org/v3/servers/009e9aca-b765-11e2-855a-</a><br>
> > 008cfa10b980"},<br>
> >      {"rel": "start",<br>
> >       "href":"<a href="http://example.org/v3/servers/009e9aca-b765-11e2-855a-" target="_blank">http://example.org/v3/servers/009e9aca-b765-11e2-855a-</a><br>
> > 008cfa10b980/start"<br>
> >       "feature": "os-start-stop"},<br>
> >      {"rel": "stop",<br>
> >       "href":"<a href="http://example.org/v3/servers/009e9aca-b765-11e2-855a-" target="_blank">http://example.org/v3/servers/009e9aca-b765-11e2-855a-</a><br>
> > 008cfa10b980/stop"<br>
> >       "feature": "os-start-stop"}.<br>
> >    ]<br>
> >   }<br>
> > }<br>
><br>
> Tht perfectly illustrates my biggest concern with doing this on a<br>
> per-resource basis.<o:p></o:p></p>
</div>
<p class="MsoNormal">Per-resource does allow you to expose whether a user has permission to<br>
perform an action, though.<o:p></o:p></p>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><br>
>  The list of "links" gets unconscionably enormous. If I do a "list"<br>
> call and retrieve 100 instances each with 100 links because you have<br>
> 20 extensions the whole thing becomes a mess. I think it's much more<br>
> sane (though less explicit) to understand what's provided by the<br>
> service and extrapolate that to the individual resources therein.<o:p></o:p></p>
</div>
<p class="MsoNormal">Yeah, lots of links can be messy. How about URI templates?<br>
<br>
Maybe we have them as a /capabilities/templates resource:<br>
<br>
  {"templates": [<br>
     {"rel": "server_start_action",<br>
      "href": "<a href="http://example.org/v3/servers/%7Bserver_uuid%7D" target="_blank">http://example.org/v3/servers/{server_uuid}</a>"<br>
     }<br>
  ]}<br>
<br>
then just do:<br>
<br>
  "links": [<br>
    {"rel": "start", "template": "server_start_action"}<br>
  ]<br>
<br>
Just a thought ...<br>
<br>
Cheers,<br>
Mark.<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal"><br>
<br>
_______________________________________________<br>
OpenStack-TC mailing list<br>
<a href="mailto:OpenStack-TC@lists.openstack.org" target="_blank">OpenStack-TC@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-tc" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-tc</a><o:p></o:p></p>
</div>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><br>
_______________________________________________<br>
OpenStack-dev mailing list<br>
<a href="mailto:OpenStack-dev@lists.openstack.org">OpenStack-dev@lists.openstack.org</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><o:p></o:p></p>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>