Hello Pablo,

Thanks for the runthrough... comments below..

Pablo Castro wrote:
[snip]
We model related entries or feeds using a link with a "rel" attribute of "related", and with a "type" of either "application/atom+xml;type=feed" or "application/atom+xml;type=entry" depending on the cardinality of the other end of the association.

One tricky aspect is that we need to indicate which association it is. At the model level we have a "navigation property" that identifies the starting "end" of the association (e.g. "Attendees", "Venue"). We currently put that name in the "title" attribute of the link. That solution is not perfect, as we try not to overload constructs that are for human-readable content. However, the alternative is to use a custom attribute, and we've been trying not to introduce custom attributes unless absolutely needed. Another option would be to use different "rel" values to specify the relationship, which feels natural but makes it much less likely that generic processors will be able to do something interesting with it.


Most generic processors aren't doing much with links yet anyway. Using specific rel attribute values would be better.

Do these trade-offs sound reasonable? Is any of the other options more 
appropriate?

Continuing with the Events sample, this is what an entry (/Events(456)) with 
links looks like:

<entry xml:base="http://localhost:81/EventsSample/";
       xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices";
       xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
       xmlns="http://www.w3.org/2005/Atom";
       m:type="EventsSample.Event">
  <id>http://localhost:81/EventsSample/Events(456)</id>
  <title type="text"></title>
  <updated>2008-02-17T02:52:38Z</updated>
  <author>
    <name />
  </author>
  <link rel="edit" title="Event" href="Events(456)" />
  <link rel="related" type="application/atom+xml;type=entry" title="Venue" 
href="Events(456)/Venue" />
  <link rel="related" type="application/atom+xml;type=feed" title="Attendees" 
href="Events(456)/Attendees" />

I'd much rather see this:

<link
   rel="http://schemas.microsoft.com/ado/2007/08/dataservices/venue";
   type="application/atom+xml;type=entry"
   title="Venue"
   href="Events(456)/Venue" />
<link
   rel="http://schemas.microsoft.com/ado/2007/08/dataservices/attendees";
   type="application/atom+xml;type=feed"
   title="Attendees"
   href="Events(456)/Attendees" />

  <content type="application/xml">
    <d:EventID m:type="Int32">456</d:EventID>
    <d:Name>Big Party</d:Name>
    <d:NoteToAttendees>It's going to be a great party!</d:NoteToAttendees>
    <d:DateAndTime m:type="DateTime">2008-03-05T06:00:00</d:DateAndTime>
  </content>
</entry>


FWIW, your content element is incorrect. There needs to be a top level element, e.g.

 <content type="application/xml">
   <d:foo>
   <d:EventID m:type="Int32">...</d:EventID>
   <d:Name>...</d:Name>
   <d:NoteToAttendees>...</d:NoteToAttendees>
   <d:DateAndTime m:type="DateTime">...</d:DateAndTime>
   </d:foo>
 </content>

> [snip]
2. Expanding links inline
[snip]
How link expansion is requested is outside of the atom-syntax problem space, so I'll just briefly state what we currently do in case you have an opinion: data services support the query string option "$expand" to request link expansion. So you could say "/Events?$expand=Attendees " to retrieve all Events and all contacts that are attendees for each of them, or "/Events(456)?$expand=Attendees" to retrieve a single event (with key 456) and its attendees. Expand syntax allows for deep expands such as "Attendees/BestFriend" (expand Attendees, and on the expanded entry(es) expand BestFriend) and wide expands such as "Venue, Attendees/BestFriend" meaning expand two immediate links, and for the Attendees one further expand its BestFriend link.


Works for me :-)

For representing expanded links we put the expanded content inside the link element itself. According to section 4.2.7 of RFC 4287:

"The "atom:link" element defines a reference from an entry or feed to a Web resource. This specification assigns no meaning to the content (if any) of this element."

So it seems that adding content to the link element is not disallowed and at the same time it does not overlap with any existing semantics given to such construct. Based on that we thought it would be the perfect place for this information, as the link itself already contains the metadata about the link that we needed.


+1. This is an excellent use of the extensibility of Atom.

When a client indicates that the target of a link should be expanded, the server responds with the Atom representation of the resources pointed at by links wrapped in an <inline> element. For example, for "/Events(456)?$expand=Attendees,Venue" the response would be:

[snip]
  <link rel="related" type="application/atom+xml;type=entry" title="Venue" 
href="Events(456)/Venue">
    <m:inline>
      <entry m:type="EventsSample.Venue">
        <id>http://localhost:81/EventsSample/Venues(789)</id>
        <title type="text"></title>
        <updated>2008-02-17T03:01:18Z</updated>
        <author>
          <name />
        </author>
        <link rel="edit" title="Venue" href="Venues(789)" />
        <link rel="related" type="application/atom+xml;type=entry" title="SalesContact" 
href="Venues(789)/SalesContact" />
        <content type="application/xml">
          <d:VenueID m:type="Int32">789</d:VenueID>
          <d:Name>The Cool Place</d:Name>
          <d:Description>Great place for parties!</d:Description>
          <d:Capacity m:type="Int32">1500</d:Capacity>
          <d:Type>Nightclub</d:Type>
        </content>
      </entry>
    </m:inline>
  </link>
[snip]

I like this approach very much. Existing (properly implemented) processors will be able to safely ignore the inline content without loss of function and would still have the ability to extract useful information from the document.

I focused on the GET operations above. We think it would be better to stay away from attempting to support full modification operations on expanded graphs. In particular, we do not handle PUT on more than one entry at a time today. We do support POSTing an expanded graph, and we simply create all the nested entries and link them to the parent entry, creating the whole graph in a single operation.


Sounds good.  PUT would definitely be problematic.

- James

Feedback in general about this approach would be greatly appreciated.

(also posted this in the Astoria team blog)

Thanks
-pablo




Reply via email to