Pablo Castro wrote: > 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.
There is no point in including a link to something totally unrelated to the entry, so it is safe to assume that *any* link references related content. rel="related" provides no useful information except to say that the link is not an alternate link (rel="alternate" is the default). Generic processors are unlikely to do anything with rel="related" that they wouldn't do for some unknown link relation. Instead of *custom* relations, we should develop common vocabularies for different domains. But, that goes against the idea of allowing users to shoehorn their existing ERD models into Atom documents, because it requires them to design with Atom in mind beforehand. > <entry> > <id>http://localhost:81/EventsSample/Events(456)</id> > <title type="text"></title> > <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" /> > <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> In this example, most of the elements of the Atom syntax (id, title, author, link/@rel, link/@title, summary) are either unused or misused. If the goal is to interoperate with other Atom implementations, I would expect the entry to look something like this: <entry> <id>http://organization.org/events/Events(456)</id> <!-- http://localhost... is never going to be a good atom:id because it is not even attempting to be globally unique. If this entry represents an event, then there is no need to have atom:id separate from the event ID. I actually recommend using urn:uuid for atom:id all the time, but that is a separate issue for another day... --> <title type="text">Big Party</title> <author> <name>A useful name</name> </author> <category scheme='http://organization.org/events' term='Event'/> <link rel="edit" title="Event" href="Events(456)" /> <link rel="http://organization.org/events/Venue" type="application/atom+xml;type=entry" title="Venue" href="Events(456)/Venue" /> <link rel="http://organization.org/events/Attendees" type="application/atom+xml;type=feed" title="Attendees" href="Events(456)/Attendees" /> <summary>It's going to be a great party!</summary> <content type="application/xml"> <d:DateAndTime m:type="DateTime">2008-03-05T06:00:00Z</d:DateAndTime> <!--Use valid Atom date constructs to represent dates/times --> </content> </entry> If you cannot nicely map the user's domain model into Atom's general purpose data model then that is a really good indication that Atom shouldn't be used. Otherwise, you aren't going to be able to interoperate usefully with anybody except other Astoria users. > 2. Expanding links inline > > As I summarized at the beginning of this note, we want to > enable clients to request whole sub-graphs of data starting > at some resource or set of resources. There are two aspects > that need to be addressed: how does the client indicate that > it wants one or more links expanded and how are the expanded > links represented on the response. > 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. How do you deal with other extensions that also embed information within the content of atom:link elements? How can you distinguish these other extensions from the expanded data? > 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. > > Feedback in general about this approach would be greatly appreciated. Instead of expanding the links within an entry, why not return a feed, where each entry represents one entity in the result set, and make use of link/@rel='alternate' or link/@rel='self'. For example: <feed> ... <entry> ... <link rel="http://organization.org/events/Venue" href="Events(456)/Venue"/> <link rel="http://organization.org/events/Attendees" href="Events(456)/Attendees"/> ... <category scheme='http://organization.org/events' term='Event'/> </entry> <entry> ... <link rel='self' href='Events(456)/Venue'/> <category scheme='http://organization.org/events' term='Venue'/> ... </entry> <entry> ... <link rel='self' href='Events(456)/Attendees'/> <category scheme='http://organization.org/events' term='Person'/> ... </entry> </feed> The consumer of the feed can see that the second and third entries are copies of the resources that are being linked to, which avoids the need to hit the server to retrieve them. This is leveraging the pre-defined Atom semantics instead of creating a new mechanism. In other words, treat "$expand" as a request to include supplementary entries in the feed. You might need a way of distinguishing the primary and supplementary entries, but that shouldn't be too hard to come up with. Notice that this scheme also seems to be easy to extend to support batch updates of multiple parts of the subgraph using whatever general batch update mechanisms become popular. - Brian
