restful-api-description-language / RADL

RADL: A description language and tooling for hypermedia-driven RESTful APIs
Apache License 2.0
23 stars 5 forks source link

Indicating scope for link relations (e.g. for feeds) #16

Closed jonathanrobie closed 9 years ago

jonathanrobie commented 9 years ago

For some representations, the meaning of a link relation depends on where it occurs in the representation. For example, in the following example from the Atom specification, the 'alternate' link relation is used (1) in the feed itself, and (2) in an entry contained in the feed. The scope of the link relation depends on where it is found. How should we handle this case?

Some possibilities:

   <?xml version="1.0" encoding="utf-8"?>
   <feed xmlns="http://www.w3.org/2005/Atom">
     <title type="text">dive into mark</title>
     <subtitle type="html">
       A &lt;em&gt;lot&lt;/em&gt; of effort
       went into making this effortless
     </subtitle>
     <updated>2005-07-31T12:29:29Z</updated>
     <id>tag:example.org,2003:3</id>
     <link rel="alternate" type="text/html"
      hreflang="en" href="http://example.org/"/>
     <link rel="self" type="application/atom+xml"
      href="http://example.org/feed.atom"/>
     <rights>Copyright (c) 2003, Mark Pilgrim</rights>
     <generator uri="http://www.example.com/" version="1.0">
       Example Toolkit
     </generator>
     <entry>
       <title>Atom draft-07 snapshot</title>
       <link rel="alternate" type="text/html"
        href="http://example.org/2005/04/02/atom"/>
       <link rel="enclosure" type="audio/mpeg" length="1337"
        href="http://example.org/audio/ph34r_my_podcast.mp3"/>
       <id>tag:example.org,2003:3.2397</id>
       <updated>2005-07-31T12:29:29Z</updated>
       <published>2003-12-13T08:29:29-04:00</published>
       <author>
         <name>Mark Pilgrim</name>
         <uri>http://example.org/</uri>
         <email>f8dy@example.com</email>
       </author>
       <contributor>
         <name>Sam Ruby</name>
       </contributor>
       <contributor>
         <name>Joe Gregorio</name>
       </contributor>
       <content type="xhtml" xml:lang="en"
        xml:base="http://diveintomark.org/">
         <div xmlns="http://www.w3.org/1999/xhtml">
           <p><i>[Update: The Atom draft is finished.]</i></p>
         </div>
       </content>
     </entry>
   </feed>```
RaySinnema commented 9 years ago

The meaning of alternate isn't actually different depending on where it is used. It means "Refers to a substitute for this context". Sure, in a different context (scope) the link typed by this relation refers to something else, but the relation between the context and the target of the link is still the same.

So the second alternative (use a naming convention) doesn't make sense. It also has the problem that people might be confused into thinking that there will be something like <link rel="alternate (in entry)">.

RaySinnema commented 9 years ago

What can we use the scope attribute for?

If it's only for generating documentation, then I think we can achieve the same using the current infrastructure in <documentation> and I would vote that we keep scope out of RADL.

gentlewind commented 9 years ago

I prefer the 'scope' option or anything else that is markable. This issue applies to any collections that have links both in the root and in the items (like HAL). I agree it is not necessary to have the 'scope' markup if only for the purpose of documentation. However, if in the near future, we (or users) develop a RADL client that can be used to validate the server implementation against RADL. The client needs to find out whether it should follow the link on the collection or collection item to validate the state transition.

RaySinnema commented 9 years ago

There is only a problem if in a single response, there are multiple links typed by the same link relation and those links are in different scopes. I have never seen that, so I don't know if this is a problem worth solving and if it is, worth spending extra markup on.

I think the presented example is contrived, because an HTML version of a collection would not be very valuable in an API, i.e. in a scenario where a program rather than a human consumes the response. I'm having trouble envisioning a realistic scenario where a REST client would retrieve an Atom feed and then follow the alternate link on the feed level to get the same information in a different format.

Maybe that's just my limited imagination :wink:. Feel free to open my eyes.

jonathanrobie commented 9 years ago

The presented example is the only example in RFC4287 that uses link relations, and the first relatively realistic example presented in the spec. I'm pretty sure I've seen interfaces that have copied that pattern. And they would be right to do so, the spec carefully identifies two distinct scopes:

The "atom:feed" element is the document (i.e., top-level) element of an Atom Feed Document, acting as a container for metadata and data associated with the feed.

The "atom:entry" element represents an individual entry, acting as a container for metadata and data associated with the entry.

When it describes metadata elements in 4.2. Metadata Elements, it says clearly that many of them can describe either the feed or the entry, where the distinction is based on scope. When it describes link relations in 4.2.7.2. The "rel" Attribute, it does so in terms of "the containing element":

The value "alternate" signifies that the IRI in the value of the href attribute identifies an alternate version of the resource described by the containing element.

The value "related" signifies that the IRI in the value of the href attribute identifies a resource related to the resource described by the containing element.

The value "self" signifies that the IRI in the value of the href attribute identifies a resource equivalent to the containing element.

I think the Atom spec is quite clear about this, and Atom's basic design has been copied by other media types that do collections. I would expect that people who look to examples to see how to use a spec will copy the first relatively complete example in the Atom spec.

The Atom specification serves as the basis

RaySinnema commented 9 years ago

I'm aware of all that. I'm also aware of Atom's history. It was not designed for REST APIs. People started using it in that context because it already existed and it somewhat met their needs. If you look at a collection media type that was specifically designed for REST APIs, like Collection+JSON, you'll see a somewhat different picture.

BTW, my experience has not been that people copy examples from the Atom spec. They use a library for working with Atom, and look at the documentation for that library. Take a look at Rome or Abdera, for example.

Anyway, none of that matters, because we have a perfectly fine solution for this problem: use <documentation>. I strongly believe that the introduction of new markup into RADL requires more use cases than just documentation, because we can already handle that.

So far the only such use case I've heard was William's test client. Well, I've written one back in the RSDL days, so I know from experience that I don't need the scope attribute for that.

As always, I'm open to be convinced by other use cases.

gentlewind commented 9 years ago

So far the only such use case I've heard was William's test client. Well, I've written one back in the RSDL days, so I know from experience that I don't need the scope attribute for that.

Do you mean by understanding the media type, a RADL test client already knows where each link relation locates and what the meaning it has? It seems right as there won't be a generic RADL client that can traverse resources without the knowledge of the server media type.

RaySinnema commented 9 years ago

Yes, the media type defines where link relations are possible and what they mean. For example, Atom does a pretty good job of that, as @jonathanrobie showed.

A test client needs to understand the media type to be able to recognize links, let alone follow them.

jonathanrobie commented 9 years ago

We don't think this needs specific support in RADL. It adds complexity that is rarely needed, especially in more modern media types.

In most cases, a more meaningful link relation name or referring to the media type documentation is a better solution.