Variants and ServerResource

7 messages Options
Embed this post
Permalink
Jonathan Hall

Variants and ServerResource

Reply Threaded More More options
Print post
Permalink
Hi,

Using 1.2 snapshot.

I'm using the @Get annotation on the ServerResource and I need to get
hold of the clients preferred language.

I've had a look and the options I see are
getClientInfo().getPreferredVariant (which you pass a list of variants
in to check against). However, this defeats the point of the @Get
matching. Or getClientInfo().getAcceptedLanguages() which returns a list
of Languages, but not in preference order.

Will adding a getClientInfo().getPreferredLanguage() (same goes for
characterset,etc) make sense or will the new VariantDescriptor Jerome
mentioned solve this? or is there another way of doing this with the new
style annotations?

Jon

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2357117
jlouvel

RE: Variants and ServerResource

Reply Threaded More More options
Print post
Permalink
Hi Jon,

For convenience, I've just added ClientInfo#getPreferredLanguage(),
getPreferredMediaType(), etc. methods.

However, proper content negotiation should take into account both client
preferences and server resource capabilities.

The plan is to support more complex @Get annotation parameters in order to
express the variants actually available:

"Resource API refactoring"
http://wiki.restlet.org/developers/172-restlet/226-restlet.html

For example, I'd like to be able to express this:

@Get("html|json * en|fr")
public Representation represent(Variant variant){
   // Check the variant and return the right representation
   ...
}

Would that work for you?

Best regards,
Jerome Louvel
--
Restlet ~ Founder and Lead developer ~ http://www.restlet.org
Noelios Technologies ~ Co-founder ~ http://www.noelios.com


-----Message d'origine-----
De : Jonathan Hall [mailto:[hidden email]]
Envoyé : samedi 30 mai 2009 15:34
À : [hidden email]
Objet : Variants and ServerResource

Hi,

Using 1.2 snapshot.

I'm using the @Get annotation on the ServerResource and I need to get
hold of the clients preferred language.

I've had a look and the options I see are
getClientInfo().getPreferredVariant (which you pass a list of variants
in to check against). However, this defeats the point of the @Get
matching. Or getClientInfo().getAcceptedLanguages() which returns a list
of Languages, but not in preference order.

Will adding a getClientInfo().getPreferredLanguage() (same goes for
characterset,etc) make sense or will the new VariantDescriptor Jerome
mentioned solve this? or is there another way of doing this with the new
style annotations?

Jon

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=23571
17

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2357611
Jonathan Hall

Re: Variants and ServerResource

Reply Threaded More More options
Print post
Permalink
Hi Jerome,

I'm not sure having getClientInfo#getPreferredLanguage(),etc using the
client preferences only is consistent with other methods such as
getPreferredVariant() which uses client and server preferences.

I would tend to add a new language for the entire application, not just
a resource.

So it makes more sense to me to create a list of languages the server
accepts. To add another language I would add the language to the list
and in the resource method it would load the appropriate language bundle
based on the negotiated language maybe by using
ClientInfo#getPreferredLanguage(). (Which would mean it acts
differently, than the implementation you added)

By having the languages in the annotation I would have to update all the
annotations, which wouldn't be ideal. Maybe we could have it so a
language in the annotation overrides the language list?

Needs more thought...

Jon


Jerome Louvel wrote:

> Hi Jon,
>
> For convenience, I've just added ClientInfo#getPreferredLanguage(),
> getPreferredMediaType(), etc. methods.
>
> However, proper content negotiation should take into account both client
> preferences and server resource capabilities.
>
> The plan is to support more complex @Get annotation parameters in order to
> express the variants actually available:
>
> "Resource API refactoring"
> http://wiki.restlet.org/developers/172-restlet/226-restlet.html
>
> For example, I'd like to be able to express this:
>
> @Get("html|json * en|fr")
> public Representation represent(Variant variant){
>    // Check the variant and return the right representation
>    ...
> }
>
> Would that work for you?
>
> Best regards,
> Jerome Louvel
> --
> Restlet ~ Founder and Lead developer ~ http://www.restlet.org
> Noelios Technologies ~ Co-founder ~ http://www.noelios.com
>
>
> -----Message d'origine-----
> De : Jonathan Hall [mailto:[hidden email]]
> Envoyé : samedi 30 mai 2009 15:34
> À : [hidden email]
> Objet : Variants and ServerResource
>
> Hi,
>
> Using 1.2 snapshot.
>
> I'm using the @Get annotation on the ServerResource and I need to get
> hold of the clients preferred language.
>
> I've had a look and the options I see are
> getClientInfo().getPreferredVariant (which you pass a list of variants
> in to check against). However, this defeats the point of the @Get
> matching. Or getClientInfo().getAcceptedLanguages() which returns a list
> of Languages, but not in preference order.
>
> Will adding a getClientInfo().getPreferredLanguage() (same goes for
> characterset,etc) make sense or will the new VariantDescriptor Jerome
> mentioned solve this? or is there another way of doing this with the new
> style annotations?
>
> Jon
>
> ------------------------------------------------------
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=23571
> 17
>
> ------------------------------------------------------
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2357611
>

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2357688
jlouvel

RE: Variants and ServerResource

Reply Threaded More More options
Print post
Permalink
Hi Jon,

Thanks for the feed-back. That's a good opportunity to move this RFE forward:

"Support generic variants in content negotiation algorithm"
http://restlet.tigris.org/issues/show_bug.cgi?id=462

First, I've modified ClientInfo#getPreferred*() methods in SVN trunk to add a parameter with the list of metadata supported by the server.

To support your approach, which makes total sense, I'm thinking about adding "supportedLanguages", "supportedMediaTypes", etc. properties on the MetadataService class. We could also have similar methods on ServerResource with a default implementation based on the parent application's MetadataService.

Then, you would just have to override the ServerResource#get(Variant) method. An alternative could be to write something like:

@Get
public Representation represent(Language lang)

or

@Get("xml")
public Representation represent(Language lang)

or

@Get
public Representation represent(MediaType mediaType, Language lang)

or

@Get
public Representation represent(Variant variant)


The parameters would be automatically provided based on content negotiation result between all available input:
 - Request#ClientInfo#getAccepted*()
 - Application#metadataService#getSupported*()
 - ServerResource#getSupported*()
 - ServerResource#getVariants()
 - annotation parameters such as @Get("xml")

How does it sound?

Best regards,
Jerome Louvel
--
Restlet ~ Founder and Lead developer ~ http://www.restlet.org
Noelios Technologies ~ Co-founder ~ http://www.noelios.com




-----Message d'origine-----
De : Jonathan Hall [mailto:[hidden email]]
Envoyé : lundi 1 juin 2009 20:07
À : [hidden email]
Objet : Re: Variants and ServerResource

Hi Jerome,

I'm not sure having getClientInfo#getPreferredLanguage(),etc using the
client preferences only is consistent with other methods such as
getPreferredVariant() which uses client and server preferences.

I would tend to add a new language for the entire application, not just
a resource.

So it makes more sense to me to create a list of languages the server
accepts. To add another language I would add the language to the list
and in the resource method it would load the appropriate language bundle
based on the negotiated language maybe by using
ClientInfo#getPreferredLanguage(). (Which would mean it acts
differently, than the implementation you added)

By having the languages in the annotation I would have to update all the
annotations, which wouldn't be ideal. Maybe we could have it so a
language in the annotation overrides the language list?

Needs more thought...

Jon


Jerome Louvel wrote:

> Hi Jon,
>
> For convenience, I've just added ClientInfo#getPreferredLanguage(),
> getPreferredMediaType(), etc. methods.
>
> However, proper content negotiation should take into account both client
> preferences and server resource capabilities.
>
> The plan is to support more complex @Get annotation parameters in order to
> express the variants actually available:
>
> "Resource API refactoring"
> http://wiki.restlet.org/developers/172-restlet/226-restlet.html
>
> For example, I'd like to be able to express this:
>
> @Get("html|json * en|fr")
> public Representation represent(Variant variant){
>    // Check the variant and return the right representation
>    ...
> }
>
> Would that work for you?
>
> Best regards,
> Jerome Louvel
> --
> Restlet ~ Founder and Lead developer ~ http://www.restlet.org
> Noelios Technologies ~ Co-founder ~ http://www.noelios.com
>
>
> -----Message d'origine-----
> De : Jonathan Hall [mailto:[hidden email]]
> Envoyé : samedi 30 mai 2009 15:34
> À : [hidden email]
> Objet : Variants and ServerResource
>
> Hi,
>
> Using 1.2 snapshot.
>
> I'm using the @Get annotation on the ServerResource and I need to get
> hold of the clients preferred language.
>
> I've had a look and the options I see are
> getClientInfo().getPreferredVariant (which you pass a list of variants
> in to check against). However, this defeats the point of the @Get
> matching. Or getClientInfo().getAcceptedLanguages() which returns a list
> of Languages, but not in preference order.
>
> Will adding a getClientInfo().getPreferredLanguage() (same goes for
> characterset,etc) make sense or will the new VariantDescriptor Jerome
> mentioned solve this? or is there another way of doing this with the new
> style annotations?
>
> Jon
>
> ------------------------------------------------------
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=23571
> 17
>
> ------------------------------------------------------
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2357611
>

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2357688

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2360849
Jonathan Hall

Re: Variants and ServerResource

Reply Threaded More More options
Print post
Permalink
Hi Jerome,

Sounds good, I think it should work.

I would add the resource bundle loading via a doInit() on a base
resource. So as long as I can access the preferred* methods to do this.
Or if doInit(MediaType mediaType, Language lang,etc) was available then
it should work great.

I'll let you know if it's fiddly in practise :)

Jon

Jerome Louvel wrote:

> Hi Jon,
>
> Thanks for the feed-back. That's a good opportunity to move this RFE forward:
>
> "Support generic variants in content negotiation algorithm"
> http://restlet.tigris.org/issues/show_bug.cgi?id=462
>
> First, I've modified ClientInfo#getPreferred*() methods in SVN trunk to add a parameter with the list of metadata supported by the server.
>
> To support your approach, which makes total sense, I'm thinking about adding "supportedLanguages", "supportedMediaTypes", etc. properties on the MetadataService class. We could also have similar methods on ServerResource with a default implementation based on the parent application's MetadataService.
>
> Then, you would just have to override the ServerResource#get(Variant) method. An alternative could be to write something like:
>
> @Get
> public Representation represent(Language lang)
>
> or
>
> @Get("xml")
> public Representation represent(Language lang)
>
> or
>
> @Get
> public Representation represent(MediaType mediaType, Language lang)
>
> or
>
> @Get
> public Representation represent(Variant variant)
>
>
> The parameters would be automatically provided based on content negotiation result between all available input:
>  - Request#ClientInfo#getAccepted*()
>  - Application#metadataService#getSupported*()
>  - ServerResource#getSupported*()
>  - ServerResource#getVariants()
>  - annotation parameters such as @Get("xml")
>
> How does it sound?
>
> Best regards,
> Jerome Louvel
> --
> Restlet ~ Founder and Lead developer ~ http://www.restlet.org
> Noelios Technologies ~ Co-founder ~ http://www.noelios.com
>
>
>
>
> -----Message d'origine-----
> De : Jonathan Hall [mailto:[hidden email]]
> Envoyé : lundi 1 juin 2009 20:07
> À : [hidden email]
> Objet : Re: Variants and ServerResource
>
> Hi Jerome,
>
> I'm not sure having getClientInfo#getPreferredLanguage(),etc using the
> client preferences only is consistent with other methods such as
> getPreferredVariant() which uses client and server preferences.
>
> I would tend to add a new language for the entire application, not just
> a resource.
>
> So it makes more sense to me to create a list of languages the server
> accepts. To add another language I would add the language to the list
> and in the resource method it would load the appropriate language bundle
> based on the negotiated language maybe by using
> ClientInfo#getPreferredLanguage(). (Which would mean it acts
> differently, than the implementation you added)
>
> By having the languages in the annotation I would have to update all the
> annotations, which wouldn't be ideal. Maybe we could have it so a
> language in the annotation overrides the language list?
>
> Needs more thought...
>
> Jon
>
>
> Jerome Louvel wrote:
>  
>> Hi Jon,
>>
>> For convenience, I've just added ClientInfo#getPreferredLanguage(),
>> getPreferredMediaType(), etc. methods.
>>
>> However, proper content negotiation should take into account both client
>> preferences and server resource capabilities.
>>
>> The plan is to support more complex @Get annotation parameters in order to
>> express the variants actually available:
>>
>> "Resource API refactoring"
>> http://wiki.restlet.org/developers/172-restlet/226-restlet.html
>>
>> For example, I'd like to be able to express this:
>>
>> @Get("html|json * en|fr")
>> public Representation represent(Variant variant){
>>    // Check the variant and return the right representation
>>    ...
>> }
>>
>> Would that work for you?
>>
>> Best regards,
>> Jerome Louvel
>> --
>> Restlet ~ Founder and Lead developer ~ http://www.restlet.org
>> Noelios Technologies ~ Co-founder ~ http://www.noelios.com
>>
>>
>> -----Message d'origine-----
>> De : Jonathan Hall [mailto:[hidden email]]
>> Envoyé : samedi 30 mai 2009 15:34
>> À : [hidden email]
>> Objet : Variants and ServerResource
>>
>> Hi,
>>
>> Using 1.2 snapshot.
>>
>> I'm using the @Get annotation on the ServerResource and I need to get
>> hold of the clients preferred language.
>>
>> I've had a look and the options I see are
>> getClientInfo().getPreferredVariant (which you pass a list of variants
>> in to check against). However, this defeats the point of the @Get
>> matching. Or getClientInfo().getAcceptedLanguages() which returns a list
>> of Languages, but not in preference order.
>>
>> Will adding a getClientInfo().getPreferredLanguage() (same goes for
>> characterset,etc) make sense or will the new VariantDescriptor Jerome
>> mentioned solve this? or is there another way of doing this with the new
>> style annotations?
>>
>> Jon
>>
>> ------------------------------------------------------
>> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=23571
>> 17
>>
>> ------------------------------------------------------
>> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2357611
>>
>>    
>
> ------------------------------------------------------
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2357688
>
> ------------------------------------------------------
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2360849
>

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=7458&dsMessageId=2360908
Stoph

Re: Variants and ServerResource

Reply Threaded More More options
Print post
Permalink
The language support is feeling a little "kludgy" to me in the current state. I would prefer the following API:
ServerResource.setLanguages(Language.ENGLISH, Language.FRENCH);
I can set this on the ServerResource instance when constructed. If the client has an invalid language preference, I would rather just use the first option in the parameter list above as the DEFAULT. If the client does not specify a language, I would prefer the same behavior.

Then use the annotations only for the Mime-Type, since the language usually does not change depending on the Mime-Type...

@Get("html")
public Representation represent(Variant variant) {
    String langCode = variant.getBestLanguage().getPrimaryTag();
    // pass langCode to my templating engine...
}
I am also interested in the preferred way to handle representations with the same (identical) representation for two or more mime-types. For example, many older browsers do not support application/xhtml+xml, so I want to treat these requests as text/html in the HTTP headers. I'm thinking I'd handle it like this? Or is this already possible/handled?
@Get("html")
public Representation represent(Variant variant) {
    return htmlRepresentation(variant, "text/html");
}
@Get("xhtml")
public Representation represent(Variant variant) {
    return htmlRepresentation(variant, "application/xhtml+xml");
}
private Representation htmlRepresentation(Variant variant, String mimeType) {
    // do the real logic here
}
These are just rough ideas intended to shape your development of Restlet 2.0. I really love this barebones HTTP framework!
jlouvel

RE: Variants and ServerResource

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)

Hi Stoph !

 

Thanks a lot for your feed-back and proposition. I’d like to note that we have the same issue with character sets and encodings which can often be orthogonal to media types.

 

In Restlet 2.0, the content negotiation algorithm has been enhanced (see org.restlet.engine.util.Conneg class) to take into account default metadata defined in the MetadataService. Those values below are used to enrich the client preferences:

 - getDefaultLanguage(): Language

 - etc.

 

Also, in the ClientInfo class, accessible in your resource with getClientInfo(), you have helper methods to select the preferred metadata among a given list:

 - getPreferredLanguage(List<Language> supported) : Language

- etc.

 

With all those pieces, you could do something like:

 

@Get("html")
public Representation represent() {
    Language lang = getClientInfo().getPreferredLanguage(myLanguages);
    // pass langCode to my templating engine...

}         

 

We just need to have getPreferredLanguage() take into account the MetadataService’s default value. This will require a bit of refactoring that I’m planning to do for 2.0 M5. In the end, you should be able to do this:

 

@Override

public void doInit(){

      getLanguages().add(Language.ENGLISH);

      getLanguages().add(Language.FRENCH);

}

 

@Get("html")
public Representation represent() {
    Language lang = getPreferredLanguage();
    // pass langCode to my templating engine...

}         

 

Would that work for you?

 

Regarding your second question, you should be able to do this in the future:

 

@Get("html|xhtml")
public Representation represent() {
    // do the real logic here

}         

 

This isn’t implemented yet, but you can look at the envisioned syntax for the annotation value here (see “Annotations parameter” section):

http://wiki.restlet.org/developers/172-restlet/226-restlet.html

 

Again, I’m planning on improving the design of ServerResource for 2.0 M5, so it is time for such feed-back and design discussion. One the goal I have in mind is to make the classic class-oriented and new annotation-oriented approaches work together more seamlessly. I’d like to have the “get(Variant)” method invoked all the time, even for annotated methods, to give a chance to intercept those calls which isn’t easy for now.

 

I’m also wondering how useful it is to keep the “variants” Map property. Maybe it would be better indeed to have separate “languages”, “mediaTypes”, “characterSets” and “encodings” properties and a getVariants(Method) method that would return the available variants for this specific resource and request.

 

I’ve updated this RFE to keep track of these ideas/tasks:

 

“Enhance ServerResource design”

http://restlet.tigris.org/issues/show_bug.cgi?id=462

 

Food for thought… J

 

Best regards,
Jerome Louvel
--
Restlet ~ Founder and Lead developer ~ http://www.restlet.org
Noelios Technologies ~ Co-founder ~
http://www.noelios.com

 

 

 

 

De : Stoph [mailto:[hidden email]]
Envoyé : lundi 17 août 2009 18:07
À : [hidden email]
Objet : Re: Variants and ServerResource

 

The language support is feeling a little "kludgy" to me in the current state. I would prefer the following API:

 
ServerResource.setLanguages(Language.ENGLISH, Language.FRENCH);

I can set this on the ServerResource instance when constructed. If the client has an invalid language preference, I would rather just use the first option in the parameter list above as the DEFAULT. If the client does not specify a language, I would prefer the same behavior.

Then use the annotations only for the Mime-Type, since the language usually does not change depending on the Mime-Type...

 
@Get("html")
public Representation represent(Variant variant) {
    String langCode = variant.getBestLanguage().getPrimaryTag();
    // pass langCode to my templating engine...
}          

I am also interested in the preferred way to handle representations with the same (identical) representation for two or more mime-types. For example, many older browsers do not support application/xhtml+xml, so I want to treat these requests as text/html in the HTTP headers. I'm thinking I'd handle it like this? Or is this already possible/handled?

 
@Get("html")
public Representation represent(Variant variant) {
    return htmlRepresentation(variant, "text/html");
}          
@Get("xhtml")
public Representation represent(Variant variant) {
    return htmlRepresentation(variant, "application/xhtml+xml");
}
private Representation htmlRepresentation(Variant variant, String mimeType) {
    // do the real logic here
}

These are just rough ideas intended to shape your development of Restlet 2.0. I really love this barebones HTTP framework!


View this message in context: Re: Variants and ServerResource
Sent from the Restlet Code mailing list archive at Nabble.com.