Re: Issue 1: Adding additional conneg metadata to _at_Produce/ConsumeXXX

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Tue, 03 Jul 2007 13:48:42 -0400

Trying to weigh the possible approaches for supporting content
negotiation based on dynamic metadata, I came up with the example of
a set of widgets that are available in few different media types and
languages but the availability differs for each widget (i.e. some are
available in one language, some in two, some have html, some just a

The first approach is my interpretation of what Jerome is suggesting
(Jerome if this isn't what you meant then please correct - I looked
at the Variant class in Restlet but I might have missunderstood its

public class Widget {

   WidgetEntity widget;

   public Widget(@UriParam("widget") String widgetId) {
     widget = findWidgetEntity(widgetId);

   List<Variant> getVariants(@HttpMethod String method) {
     List<Variant> variants = new ArrayList<Variant>();
     for (MediaType type: widget.getTypes()) {
       for (String lang: widget.getLanguages()) {
         Variant v = new Variant(type, lang);
     return widget.getTypes();

   public InputStream getWidget(@HttpContext Variant v) {
     return widget.getStream(v.type, v.lang);

In the above, the runtime:

(i) calls the constructor,
(ii) calls the getVariants method to obtain a list of possible
variants for the current request (I added a @HttpMethod since it
seems possible that you'd want to return different things depending
on the method though that isn't shown above, you could also use any
of the other annotations that can be used on a resource method).
(iii) perform the conneg matching and either returns an appropriate
error if there's no acceptable variant or
(iv) calls the getWidget method passing in the selected variant (note
there's no need to set the negotiated metadata since the runtime can
do that automatically. If an application wanted to add metadata then
it would need to return Response and create one from the passed in

An alternate approach is my interpretation of what Paul is suggesting:

public class Widget {

   WidgetEntity widget;
   @HttpContext AcceptabilityEvaluator ae;

   public Widget(@UriParam("widget") String widgetId) {
     widget = findWidgetEntity(widgetId);

   public Response getWidget() {
     Response.Builder rb = ae.evaluate(widget.getTypes(),
     if (rb.getStatus() < 300)
       rb.entity(widget.getStream(rb.getType(), rb.getLanguage()));

In the above, the runtime calls the constructor followed by the
getWidget method and the application uses the
"AcceptabilityEvaluator" to determine if there is an acceptable
response or not. The ae.evaluate method returns an appropriate error
response if there's no acceptable combination or a prefilled OK
response if there is. The application adds an entity if required and
return the response.

Personally I prefer the second approach for the following reasons:

- There's no need to build a list of variants every time
- The context of the request is implicit since the conneg occurs
directly in the method that will service the request
- The application gets a chance to tweak or override the default
error response when no matching variant is found

Thoughts, comments ?

On Jun 30, 2007, at 3:02 AM, Jerome Louvel wrote:

> Hi Mark,
>>> It seems that you mix the ability to expose dynamic representation
>>> metadata
>>> and the content negotiation algorithm (interpreting the Accept*
>>> headers).
>> I don't think its really a matter of mixing them, rather the runtime
>> hands off to the application when there isn't sufficient static
>> information to make a determination.
> The conneg algo doesn't need to rely on static metadata only. It could
> perfectly work on dynamic metadata too (like we do in Restlet).
>>> For the first one, we should just have annotation ways to
>> expose those metadata, and for some rare cases rely on an
>> "EntityProvider" service.
>> I don't think EntityProvider is related to dynamic metadata. You can
>> associate some static metadata with one (ConsumeMime, ProduceMime)
>> but by the time an EntityProvider enters the process all of the
>> conneg will have already taken place.
> Why does it have to be processed this way? If you design the API for a
> stricter separation between the resources/representations and
> conneg algo,
> this perfectly possible IMHO.
>> For "annotation ways to expose those metadata" do you mean something
>> like an annotated method that would return, say, the list of
>> available languages ?
> Yes, and not only for languages. The notion of variant (consistent
> set of
> metadata) is important too.
> Best regards,
> Jerome
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

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