dev@jsr311.java.net

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

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 09 Jul 2007 11:39:33 +0200

Hi Jerome,

When i read back through the thread it is hard for me to understand what
you are proposing as my understanding keeps changing.

If you have the time it would be most helpful if you could provide a
concrete example of what you are proposing.

I get the impression you are proposing to return a list of
'representation+meta-data' (concretely it could be a list of Response)
from which one 'representation+meta-data' will be selected and returned
as the response to a GET request. But, I really don't want to speculate
any further :-)

Paul.

Jerome Louvel wrote:
> Hi Marc,
>
> Thanks for looking at the Variant approach in Restlet. I wasn't actually
> proposing to separate the concept of Variant and Representation in the
> JSR-311. I think that we can abstract things a little more by only exposing
> "available representations", therefore removing the need for a
> getWidget(variant) method.
>
>> - There's no need to build a list of variants every time
>
> You have taken a case where all the types are available in all the
> languages, which looks simpler with Paul's Response.Builder. But have you
> considered the case where a language is not available for certain types? You
> could also take into account more dimensions: encoding and character set.
> The situations where all the combinations are available is rare. Therefore
> the Variant approach offers more precision and flexibility.
>
>> - The context of the request is implicit since the conneg occurs
>> directly in the method that will service the request
>
> With proper conneg in place, there is no need for extra processing in the
> case of GET/HEAD methods in 95% of cases.
>
>> - The application gets a chance to tweak or override the default
>> error response when no matching variant is found
>
> Then, a GET method handler could be exposed, disconnecting or tweaking the
> default conneg behavior...
>
> Best regards,
> Jerome
>
>> -----Message d'origine-----
>> De : Marc.Hadley_at_Sun.COM [mailto:Marc.Hadley_at_Sun.COM]
>> Envoyé : mardi 3 juillet 2007 19:49
>> À : dev_at_jsr311.dev.java.net
>> Objet : Re: Issue 1: Adding additional conneg metadata to
>> @Produce/ConsumeXXX
>>
>> 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
>> jpeg).
>>
>> 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
>> use):
>>
>> @UriTemplate("widgets/{widget}")
>> public class Widget {
>>
>> WidgetEntity widget;
>>
>> public Widget(@UriParam("widget") String widgetId) {
>> widget = findWidgetEntity(widgetId);
>> }
>>
>> @Variants
>> 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);
>> variants.add(v);
>> }
>> }
>> return widget.getTypes();
>> }
>>
>> @HttpMethod
>> 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
>> Variant.
>>
>> An alternate approach is my interpretation of what Paul is suggesting:
>>
>> @UriTemplate("widgets/{widget}")
>> public class Widget {
>>
>> WidgetEntity widget;
>> @HttpContext AcceptabilityEvaluator ae;
>>
>> public Widget(@UriParam("widget") String widgetId) {
>> widget = findWidgetEntity(widgetId);
>> }
>>
>> @HttpMethod
>> public Response getWidget() {
>> Response.Builder rb = ae.evaluate(widget.getTypes(),
>> widget.getLanguages());
>> if (rb.getStatus() < 300)
>> rb.entity(widget.getStream(rb.getType(), rb.getLanguage()));
>> return rb.build();
>> }
>> }
>>
>> 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 ?
>> Marc.
>>
>>
>> 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: dev-unsubscribe_at_jsr311.dev.java.net
>>> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>>>
>> ---
>> Marc Hadley <marc.hadley at sun.com>
>> CTO Office, Sun Microsystems.
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
>> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_jsr311.dev.java.net
> For additional commands, e-mail: dev-help_at_jsr311.dev.java.net
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109