dev@jsr311.java.net

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

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Mon, 09 Jul 2007 15:53:27 -0400

On Jul 7, 2007, at 6:49 AM, Jerome Louvel wrote:
>
> 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.
>
As I said in a previous mail, I don't really understand what you are
proposing here, a concrete example would be great.

>> - 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.
>
I did consider that, essentially you would then need to make a series
of calls to the AcceptabilityEvaluator.evaluate method and check the
return from each one. If there were no overlap between combinations
then each call to AcceptabilityEvaluator.evaluate would correspond to
a new Variant in the other approach.

>> - 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.
>
By context, I meant the request method and taking account of the
statically declared metadata.

>> - 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...
>
Again, I don't really understand what you are proposing so I can't
see how that would work. A concrete example would really help to
clarify.

Thanks,
Marc.

>
>> -----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
>

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