RE: Content negotiation with browsers - advice sought

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
Report Content as Inappropriate

RE: Content negotiation with browsers - advice sought


Hi Jon,

Good suggestion! I've added a RFE for this:

"Enhance documentation on conneg" 

If you are interested in contributing some doc on this topic, we could
create a new web page in our User Guide (wiki) for this.

Best regards,
Jérôme Louvel
Restlet ~ Founder and Lead developer ~
Noelios Technologies ~ Co-founder ~

-----Message d'origine-----
De : [hidden email] [mailto:[hidden email]] De la part de Jon
Envoyé : jeudi 30 octobre 2008 10:06
À : [hidden email]
Objet : Re: Content negotiation with browsers - advice sought

Thanks Stephan, this is very helpful.  I think that some documentation
on this subject would be valuable, either in the Javadoc for the
TunnelService or elsewhere on the Restlet website.  It would be useful
to clarify:

1) General background on content negotiation and how it's supposed to
work in REST - and how some web browsers break the model (perhaps
there are some external pages that can simply be referenced).
2) How Restlet handles content negotation: by default and with the use
of tunnels.
3) How to add different file extension-media type mappings and how to
find out which ones are provided by default.
4) Similarly, how to add different user agent mappings and what the
defaults are.

Best wishes,

On Tue, Oct 28, 2008 at 7:52 PM, Stephan Koops <[hidden email]> wrote:
> Hi Jon
>> 1) Is the TunnelService essentially a filter that can modify HTTP
>> headers (possibly other things too) before they reach my Resource
>> class?
> The Restlet Engine uses the data from the TunnelService to initialize the
TunnelFilter (part of the engine), which does the work, as you described. As
every filter, it could change everything in the request.
>> 2) Why do you consider the userAgentTunnel better than file
>> extensions?  Is it simply closer to the REST model?
> The user agnet filter allow the content negotiation as it is planned,
because you are not required to add extensions to your URIs. On the other
hand with the extension mapping you have the possibility to request every
media type with every client. You could also combine both possibilities.
> To the closeness to REST: While defining the JAX-RS-API we had a
discussion about exactly this feature. Roy Fielding pointed out (see, full
=1196535&count=31&by=thread&paged=false) , that he URI is not the same resource as, and he
is right. These URIs describe two resources, which could (should, ...) point
to the same entity (the same business object, see
_2_1_1 for details).
> With reading it is not a big problem, but with modifying: if you edit
...../fgh.html (e.g. PUT or DELETE), than this request (from the REST point
of view) will not change/delete ..../fgh.xml, but this is the result,
intended by the developer and the client. So the user agent filter is indeed
closer to REST. The Restlet filter will evaulate the extension only for GET
(and HEAD) requests.
> But I think, that both are useful. IMO: Use both. If the link is .../fgh
(without extension), you get, what your client like (HTML for browser etc,
XML or JSON for a web servcie etc.), and if you want a special media type,
you could explict use the URI ...../fgh.gif

>> 3) If I use a userAgentTunnel how can I distinguish between web page
>> requests (which probably require text/html) and requests from <img>
>> tags (which probably require image/*)?
> See above.
>> 4) What's the best documentation to read to learn how to use and
>> configure the TunnelService?  I can probably figure things out from
>> the javadoc, but would appreciate some other docs if they exist.
> I don't knoiw, that there is more documentation. You just need to set the
booleans to true. The Restlet Engine should do the rest. It includes a lot
of mappings for file extensions (see
org.restlet.service.MetadataService.getMetaData(), accessible via
Application.getMetadataService()). It also includes a basic configuration
for the user agent mapping. There is a propertiy file for it, but I don't
know where. Perhaps or something like this.
> If you have more questions, there is thsi mailing list :-) Perhaps you
give good input for more javadoc or something like this.
> best regards
>   Stephan
>> On Tue, Oct 28, 2008 at 11:51 AM, Stephan Koops <[hidden email]>
>> > Hi Jon,
>> >
>> > in the TunnelService in Restlet 1.1 there is a solution for exactly
this problem. Try Application.getTunnelService().setUserAgentTunnel(true).
>> > Your proposed workaround with file extensions is also available: Try

>> > But the first solution is IMO better.
>> >
>> > best regards
>> >   Stephan
>> >
>> >> -----Ursprüngliche Nachricht-----
>> >> Von: "Jon Blower" <[hidden email]>
>> >> Gesendet: 28.10.08 12:34:26
>> >> An: "Restlet discussion mailing list" <[hidden email]>
>> >> Betreff: Content negotiation with browsers - advice sought
>> >>
>> >> Hi all,
>> >>
>> >> I am using Restlet to create a simple data server.  I'm currently
>> >> wrestling with content negotiation (conneg), which is handled very
>> >> nicely by Restlet, but not by user agents, particularly web browsers.
>> >>
>> >> I'd like to be able to serve representations of my resources in a
>> >> number of formats, including HTML, Google Earth KML and a special XML
>> >> format called CSML (  I have set up my
>> >> Resource object to support a number of Variants:
>> >>
>> >>   getVariants().add(new Variant(MediaType.TEXT_HTML));  // for web

>> >>   getVariants().add(new Variant(CSML_MEDIA_TYPE)); // for special
>> >> clients that understand CSML
>> >>   getVariants().add(new Variant(MediaType.IMAGE_PNG)); // image
>> >> representation of the resource
>> >>   getVariants().add(new Variant(KML_MEDIA_TYPE)); // for clients that
>> >> understand KML
>> >>   getVariants().add(new Variant(MediaType.APPLICATION_XML)); // for
>> >> general clients that understand XML but not CSML
>> >>
>> >> I had naively assumed that web browsers would automatically ask for
>> >> and get the TEXT_HTML representation.  But no, I tested Firefox, IE7
>> >> and Chrome and got very different results:
>> >>
>> >> Firefox 3: Accept header is
>> >> "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8".
>> >> Hence text/html is used, as expected.
>> >>
>> >> Chrome Accept header is
>> >>

>> >>  So Chrome prefers application/xml to text/html and hence gets an XML
>> >> representation by default.  Seems odd.
>> >>
>> >> IE7: Accept header does not include text/html, image/png or
>> >> application/xml (!!) but does include "*/*" (yuck) so IE gets the
>> >> variant that happens to be first in the Resource's list.  With the
>> >> above code this just happens to be text/html.  So conneg doesn't
>> >> really happen here at all.
>> >>
>> >> I didn't test Safari, Opera or anything else.
>> >>
>> >> So the question is, how can arrange things so that web browsers get
>> >> HTML representations?  I can only see one workaround for this, which
>> >> is to use "file" extensions on my resource URLs to determine the media
>> >> type (e.g. .html, .png, .kml etc).  This is not RESTful (from my
>> >> understanding of REST) but seems to be a common workaround (e.g. in
>> >> Ruby on Rails).  Is there a way to do this easily in Restlet or is
>> >> this practice discouraged?
>> >>
>> >> Or is there a better alternative?
>> >>
>> >> Best wishes,
>> >> Jon
> _______________________________________________________________________
> Jetzt neu! Schützen Sie Ihren PC mit McAfee und WEB.DE. 30 Tage
> kostenlos testen.

Dr Jon Blower
Technical Director, Reading e-Science Centre
Environmental Systems Science Centre
University of Reading
Harry Pitt Building, 3 Earley Gate
Reading RG6 6AL. UK
Tel: +44 (0)118 378 5213
Fax: +44 (0)118 378 6413
[hidden email]