Creating hypermedia links in a custom media-type

2020-06-03 08:29发布

问题:

I am currently creating a set of custom media types for a RESTful api (e.g. application/vnd.mycompany.foo+xml) and I'm trying to identify the pros and cons of two different ways of exposing hypermedia links.

If I first consider what other media types do probably the best place to start is HTML. Html allows me to create links such as:

<image src="http://example.com/image.gif"/>
<a href="http://example.com/page.html"/>
<form action="http://example.com/page.html"/>
<link rel="stylesheet" type="text/css" href="theme.css" />

The interesting thing here is that in some cases there some specific tags that have an url attribute and then there is the generic link tag that using the rel attribute to define the relationship.

In AtomPub, there are also a few ways that resources are linked together

<collection href="http://example.org/blog/main" >
         <atom:title>My Blog Entries</atom:title>
         <categories href="http://example.com/cats/forMain.cats" />
</collection>

<atom:category scheme="http://example.org/extra-cats/" term="joke" />
<atom:entry>
   <link rel="edit" href="http://example.org/edit/first-post.atom"/>
</atom:entry>

The question that I am asking is when does it make more sense to use a link element with a relationship, and when does it make more sense to add an attribute to an existing element.

e.g. the AtomPub links could have been done

<collection>
      <link rel="source" href="http://example.org/blog/main"/>
         <atom:title>My Blog Entries</atom:title>
         <categories>
                <link rel="source" href="http://example.com/cats/forMain.cats"/>
         </categories>
</collection>

<atom:category term="joke">
     <link rel="scheme" href="http://example.org/extra-cats/"/>
<atom:category>
<atom:entry edit="http://example.org/edit/first-post.atom"/>

As is frequently the case, in writing this question, the answer seems now to be obvious. The required links are exposed as attributes and optional ones as elements. However, I would be very interested in hearing other people's opinions about how they think links should be represented.

回答1:

What I liked about XHTML 2 was that every element could have a link.

Why not leverage XLink to enable the same funcitonality? That way, no need to choose.



回答2:

I believe semantically your two Atom examples are equivalent. There are a few places in the Atom spec where a link with no relation is considered the default link (whether they call is "self" or "source" I don't remember). Personally I like the second AtomPub example the best, because the link elements in an Atom Entry (which is the most used object when dealing with Atom in general) defines link elements with relations, and using the same schema in category, collection, and workspace elements means it's easier to parse w/o needing to know a lot of special conditions.

I kind of ignore the first HTML example because original HTML was never really intended for machine communication in the way Atom is, and therefor (IMO) semantically understanding HTML is more difficult and waters down to a lot of specific rules to handle every different kind of tag.



回答3:

Thats an interesting question. One way to look at it would be to differentiate links into "informational" links that link to related resources, that the client may (or may not) want to follow to get more information (like the <categories> element in atompub).

On the other hand are the links that "define" the protocol, i.e. that "guide" the client through the sequence of state changes (e.g. publish/edit/delete in the case of Atompub, or order/review/pay in a shopping system) of a resource that make up the actual protocol (like <link rel="edit">).

In the Starbucks article, the authors expand the whole idea by defining a (hypothetical) schema for state changes. They're using <next rel="schema url" uri="uri for next resource state"> instead of Atom's <link rel="..." href="...">, but the general idea is the same.

Of course, one could argue that following any link represents a state change for the client. But I think this distinction makes sense.