{"id":74,"date":"2009-07-09T21:08:40","date_gmt":"2009-07-10T04:08:40","guid":{"rendered":"http:\/\/www.corneliadavis.com\/blog\/?p=65"},"modified":"2009-07-09T21:08:40","modified_gmt":"2009-07-10T04:08:40","slug":"atom-extension-for-hierarchy","status":"publish","type":"post","link":"https:\/\/corneliadavis.com\/blog\/2009\/07\/09\/atom-extension-for-hierarchy\/","title":{"rendered":"Atom extension for hierarchy"},"content":{"rendered":"<p>There has been a bit of a debate going on in <a href=\"http:\/\/www.oasis-open.org\/committees\/cmis\/\">CMIS<\/a> on this topic and I\u2019m interested in thoughts from members of the REST and\/or Atom community so am posting a synopsis here.  The CMIS mailing list is open to the public and you can see the most recent thread on the subject <a href=\"http:\/\/lists.oasis-open.org\/archives\/cmis\/200907\/msg00267.html\">here<\/a> and from there can find other postings if you are interested enough to dig that deep.  I give a pretty thorough overview here if you don\u2019t have the cycles to follow the links.The subject at hand is how to represent a hierarchy of entities in atom.  Atom, of course, has a feed and an entry but there is no mechanism for embedding a feed either in another feed, or embedding a feed inside of an entry.  I\u2019m not really looking for feedback here that questions whether hierarchical representations are a good idea or not \u2013 CMIS has made the decision that they need them \u2013 so assuming we are going to represent them, the question is, what is the best approach.Over the last couple of months we\u2019ve spoken with <a href=\"http:\/\/o-micron.blogspot.com\/\">Nikunj Mehta<\/a> who is the author of an I-D on <a href=\"http:\/\/tools.ietf.org\/html\/draft-mehta-atom-inline-01\">In-lining Extensions for Atom<\/a> that defines a mechanism that could be used for hierarchical arrangements by embedding representations as child elements to the atom link relation.  Because the requirements driving the I-D and CMIS differ, and because it seems that the I-D will likely take a fair bit of time to reach consensus, the CMIS TC has decided to create their own extension with an intent to replace this with an applicable standard once one is available.All of that context established, the CMIS TC has considered several options and has down-selected to two \u2013 those that we are calling option 3 and option 4 (options 1 and 2 already having been dismissed).What we refer to as option 3 is one where a folder entry has a cmis:children element that contains multiple atom:entry elements.  In outline form it looks like:<code>&lt;atom:entry>&nbsp;&nbsp;&lt;atom:title>Folder A&lt;\/atom:title>&nbsp;&nbsp;...&nbsp;&nbsp;&lt;cmis:children>&nbsp;&nbsp;&nbsp;&nbsp;&lt;atom:entry>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;atom:title>Folder B&lt;\/atom:title>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/atom:entry>&nbsp;&nbsp;&nbsp;&nbsp;... more atom entries ...&nbsp;&nbsp;&lt;\/cmis:children>&lt;\/atom:entry><\/code>What we refer to as option 4 is one where a folder entry has a cmis:children element that wraps an atom:feed element that then contains multiple atom:entry elements.<code>&lt;atom:entry>&nbsp;&nbsp;&lt;atom:title>Folder A&lt;\/atom:title>&nbsp;&nbsp;...&nbsp;&nbsp;&lt;cmis:children>&nbsp;&nbsp;&nbsp;&nbsp;&lt;atom:feed>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... a bunch of feed stuff ...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;atom:entry>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;atom:title>Folder B&lt;\/atom:title>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/atom:entry>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... more atom entries ...&nbsp;&nbsp;&nbsp;&nbsp;&lt;atom:feed>&nbsp;&nbsp;&lt;\/cmis:children>&lt;\/atom:entry><\/code>Option 3 has at least two advantages over option 4:<\/p>\n<ul>\n<li>Option 3 will have a smaller representation because it does not include the feed and the elements that are required of a feed (i.e. the \u201cbunch of feed stuff\u201d shown in option 4 above)<\/li>\n<li>Option 3 results in a simpler server side implementation because the feed needn\u2019t be created.<\/li>\n<\/ul>\n<p>In spite of these advantages I believe that option 3 has one significant disadvantage over option 4, and that is that we fundamentally have two different representations for the same resource, requiring that client developers must have two implementations of a function depending on how the resource representation was retrieved.  Let me explain with an example.Suppose a client developer has written some code to display certain things about a children collection \u2013 they want to display the name of the collection, the last updated value, a list of the children and they want to have a button that allows the user to select this location as a target of a new item creation.  This code executes against a feed retrieved via the URL to that child collection (URL could have been bookmarked for example).  The pseudocode for this is something like:<code>void processCollectionResource(feed childrenResource) {&nbsp;&nbsp;String title = childrenResource.getTitle();&nbsp;&nbsp;Date lastModified = childrenResource.getUpdated();&nbsp;&nbsp;\/\/ get the URL of the link relation with rel=\u201dself\u201d&nbsp;&nbsp;URL postURL = childrenResource.getLinkURL(\u201cself\u201d);&nbsp;&nbsp;Iterate childrenResource.getEntries() {&nbsp;&nbsp;&nbsp;&nbsp;\/\/ so something with each child&nbsp;&nbsp;&nbsp;&nbsp;\/\/ &nbsp;&nbsp;&nbsp;&nbsp; (this will be the same in both cases)&nbsp;&nbsp;}&nbsp;&nbsp;\/\/ do something with all of this \u2013 render, etc.}<\/code>Now the client realizes they want to do the same thing but against a set of children that are embedded within a hierarchical representation.  Let\u2019s first look at the pseudocode for option 4.There is code that has to parse the child collection out \u2013 it is something like the first line of:<code>feed childrenResource = folderResource.getChildren().getFeed();processCollectionResource(childrenResource);<\/code>The processCollectionResource method can be used as is.For option 3, I need to pass in the folder resource and start navigating from there, because some of the information I need is at the folder and some of it is in the cmis:children element.  So I\u2019d make a call something like:<code>processCollectionResourceEmbedded(folderResource);<\/code>And the new code to process this slightly different representation is:<code>void processCollectionResourceEmbedded(entry folderResource) {&nbsp;&nbsp;String title = folderResource.getTitle();&nbsp;&nbsp;Date lastModified = folderResource.getUpdated();&nbsp;&nbsp;\/\/ get the URL of the link relation with rel=\u201ddown\u201d&nbsp;&nbsp;\/\/ NOTE!!!! that the code is less self contained here \u2013 self&nbsp;&nbsp;\/\/ is more direct than down&nbsp;&nbsp;URL postURL = folderResource.getLinkURL(\u201cdown\u201d);&nbsp;&nbsp;Iterate folderResource.getChildren().getEntries() {&nbsp;&nbsp;&nbsp;&nbsp;\/\/ so something with each child&nbsp;&nbsp;&nbsp;&nbsp;\/\/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(this will be the same in both cases)&nbsp;&nbsp;}&nbsp;&nbsp;\/\/ do something with all of this \u2013 render, etc.}<\/code>At the root of this difference is that with option 4 we are treating the set of children as a full-fledged, stand alone resource.  This allows us, for example, to have different metadata for the children collection as for the folder itself (the CMIS domain model doesn\u2019t make this distinction, however, option 4 would allow for this which is goodness).  The children resource representation is self-contained \u2013 I don\u2019t have to go up to the containing folder to find out something about the collection.  Option 3 doesn\u2019t really treat the children resource as a complete resource &#8211; it depends on the folder resource to describe something about the children collection resource.I\u2019m sure it\u2019s not lost on anyone that with option 3 we are creating a new, proprietary (to CMIS), feed-like container mechanism with the cmis:children element instead of using the standardized one that already exists.  I don\u2019t think that is a good idea.Finally, and perhaps most subtle, is the fact that with option 3 we are really treating the document that is retrieved as the unit of importance, because we are requiring more than just the representation of the children collection in order to process it.  I am extremely interested in seeing CMIS provide support for more than just the document web, pushing into support for the linked data web.  Atom is designed to support it \u2013 I don\u2019t want to loose that with a poorly designed extension to atom.Sure, embedding a feed duplicates some of the values from the folder entry to the feed (for CMIS), but I think that is a reasonable trade for the simplicity and elegance that it offers the client.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There has been a bit of a debate going on in CMIS on this topic and I\u2019m interested in thoughts from members of the REST and\/or Atom community so am posting a synopsis here. The CMIS mailing list is open to the public and you can see the most recent thread on the subject here [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[33],"tags":[50,54,73],"class_list":["post-74","post","type-post","status-publish","format-standard","hentry","category-standards","tag-atom","tag-cmis","tag-linkeddata"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/74","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/comments?post=74"}],"version-history":[{"count":0,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/74\/revisions"}],"wp:attachment":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/media?parent=74"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/categories?post=74"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/tags?post=74"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}