Re: Hyperlinks and content negotiation

First, let me reiterate an argument from last year's discussion: are
you proposing also adding accept-language, accept-encoding and other
accept-* attributes? If not, then you're only solving a very small
part of the problem (provided there's a problem to be solved).
Also, why couldn't UAs tweak their Accept-* headers depending on
type="" and hreflang="" attribute values?

The problem is that you want to leverage HTTP's ability to
transparently provide variants for a same resource, and at the same
time you want to be able to link to a specific variant. If you link to
something, isn't it a resource on its own? (i.e. with its own URI)
You're now bringing cache invalidation as an argument, but that's
already solved by RFC 2295 and RFC 2296.

On Mon, Oct 19, 2009 at 1:51 PM, Mike Kelly <mike@mykanjo.co.uk> wrote:
>
>>> Without a formal mechanism in HTML which can specify to UAs the
>>> contextual content-type preference for a given hyperlink, HTML is not
>>> a viable hypermedia format for systems which must rigorously leverage
>>> HTTP conneg
>>
>> What systems "must rigorously leverage HTTP connect" (and what
>> does that mean?)
>
> I was trying to describe implementations which rely exclusively on conneg
> for negotiating representations of resources and deliberately avoid using
> multiple URIs for this purpose.
>
> JSR 311 (JAX-RS) is an example technology with this constraint
>
> https://jsr311.dev.java.net/nonav/releases/1.1/spec/spec3.html#x3-320003.5

I'm far from being a JAX-RS expert but AFAICT, JAX-RS doesn't rule out
those three cases:
/*
 * Representations of the same data at two distinct URLs
 */
@Path("blog")
public class BlogResource {
   @GET @Path("index.html") @Produces("text/html")
   public String getAsHtml() { ... }

   @GET @Path("index.atom") @Produces("application/atom+xml")
   public String getAsAtomFeed() { ... }
}

/*
 * same as above, but also provides a conneg'd URL.
 * TODO: add Content-Location response header
 */
@Path("blog")
public class BlogResource {
   @GET @Path("feed") @Produces("application/rss+xml")
   public Response getAsRss20() { ... }

   @GET @Path("feed") @Produces("application/atom+xml")
   public Response getAsAtomFeed() { ... }

   @GET @Path("feed\\.{format:rss|atom}")
   @Produces("application/rss+xml", "application/atom+xml")
   public Response getAsNegotiated(@Context Request request,
         @PathParam("format") format) {
      if (".atom".equals(format)) {
         return getAsAtomFeed();
      } else {
         assert ".rss".equals(format);
         return getAsRss20();
      }
   }
}

/*
 * same as above, the other way around
 */
@Path("blog")
public class BlogResource {
   private static final MediaType APPLICATION_RSS_XML_TYPE =
      new MediaType("application", "rss+xml");
   private static final List<Variant> VARIANTS = Variant.mediaTypes(
      MediaType.APPLICATION_ATOM_XML_TYPE,
      APPLICATION_RSS_XML_TYPE).build();

   @GET @Path("feed.atom") @Produces("application/atom+xml")
   public Response getAsAtomFeed() { ... }

   @GET @Path("feed.rss") @Produces("application/rss+xml")
   public Response getAsRss20() { ... }

   @GET @Path("feed")
   @Produces("application/rss+xml", "application/atom+xml")
   public Response getAsNegotiated(@Context Request request) {
      Variant variant = request.selectVariant(VARIANTS);
      // variant should be non-null thanks to the @Produces annotation
      if (MediaType.APPLICATION_ATOM_XML_TYPE.equals(variant.getMediaType())) {
         return
      } else {
         // should be RSS
      }
   }
}

-- 
Thomas Broyer
/tɔ.ma.bʁwa.je/

Received on Monday, 19 October 2009 14:17:36 UTC