dev@jsr311.java.net

Issue 1 - Proposal for new conneg APIs

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Thu, 11 Oct 2007 11:48:03 -0400

Issue 1[1] asks about additional support for content negotiation.
I've uploaded a sketch of some new APIs to aid with content
negotiation beyond the media type support we currently have:

https://jsr311.dev.java.net/nonav/sketches/conneg/index.html

RepresentationVariant represents an available combination of media
type, language, charset and encoding. Its ListBuilder static inner
class is a builder that makes creation of a list of variants
straightforward.

RequestHelper would replace the existing PreconditionEvaluator and
adds support for conneg to the existing precondition methods. I also
added a notAcceptable method to Response.Builder and an extra
representation method to directly support RepresentationVariant.

The idea is that you use RepresentationVariant.ListBuilder to create
a list of variants that describe all of the possible representations
that can be produced. You then use RequestHelper.narrowChoices to
select a variant that matches the preferences in the request. Once
you've narrowed the choices you can then proceed to evaluate
preconditions for the chosen variant.

Here's an example of how it could be used.

@HttpContext RequestHelper req;

@HttpMethod
public Response getFoo() {
   RepresentationVariant.ListBuilder b =
RepresentationVariant.ListBuilder.newInstance();
   b.mediaTypes("application.xml", "application.json");
   b.languages("en", "fr");
   List<RepresentationVariant> variants = b.add().build();

   // check we have a representation that is acceptable
   RepresentationVariant v = req.narrowChoices(variants);
   if (r==null)
     return Response.Builder.notAcceptable(variants);

   // check preconditions
   Response r = req.evaluatePreconditions(getTag(v), v);
   if (r!=null)
     return r;

   // have a representation and preconditions were met
   return Response.Builder.representation(getEntity(v), v);
}

I can see the above pattern being repeated over and over and I'm
wondering if there's some way we can automate it to make it more
convenient - perhaps via a callback interface or something. Either
way I suspect we need the lower level approach above for maximum
flexibility.

BTW, RepresentationVariant is somewhat similar to the Variant class
in the RESTlet API. The main difference is that a variant in RESTlet
includes all the representation metadata whereas
RepresentationVariant only includes metadata used for conneg.

Let me know what you think.

Marc.

[1] https://jsr311.dev.java.net/issues/show_bug.cgi?id=1
[2] http://www.restlet.org/documentation/1.0/api/

---
Marc Hadley <marc.hadley at sun.com>
CTO Office, Sun Microsystems.