dev@jsr311.java.net

Re: JSR311: URI-based conneg

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Mon, 03 Mar 2008 15:52:39 -0500

On Mar 3, 2008, at 2:07 PM, Stephan Koops wrote:

> Why not support languages, for example: GET /foo.en.xml ? I think,
> it is very useful to be used by browsers.
> I tried to look in the mailing list archive, but it didn't answer.
>
I think we did discuss that but, IIRC, things got complex in the
general case once you add more than one extension.

Marc.

>
> Marc Hadley schrieb:
>> Any other feedback on this proposal ? When we discussed it
>> originally the EG seemed to be generally in favour of adding this
>> kind of functionality - is that still the case ?
>>
>> Marc.
>>
>> On Feb 19, 2008, at 12:46 PM, Marc Hadley wrote:
>>
>>> I'd like to revive a thread started way back in Sept last year,
>>> see: https://jsr311.dev.java.net/servlets/ReadMsg?list=dev&msgNo=650
>>>
>>> The topic was support for URI-based content negotiation,
>>> essentially allowing a client to
>>>
>>> GET /foo.xml
>>>
>>> as an alternative to
>>>
>>> GET /foo
>>> Accept: application/xml
>>>
>>> I'd like to offer the following concrete proposal:
>>>
>>> - We only offer automatic support for content types, nothing for
>>> language or charset negotiation.
>>>
>>> - When the feature is enabled:
>>>
>>> * A request URI that ends with an extension is matched as if that
>>> extension were not present. E.g. @Path("widgets") would match
>>> requests for widgets, widgets.xml and widgets.json
>>>
>>> * If a URI template ends in a variable then the variable value is
>>> injected without the extension. E.g. @Path("widgets/{id}") with
>>> request for widgets/1.xml and @PathParam("id") String id would
>>> result in a value of "1" for id.
>>>
>>> * The extension is compared to the keys in
>>> ApplicationConfig.getExtensionMappings (Map<String, MediaType). If
>>> a match is found any Accept header value is replaced with the
>>> value for the matching key.
>>>
>>> - An @Path property style is provided to control the behavior. A
>>> value of 'platonic' means that the path should be treated as part
>>> of a platonic URI and the above behaviour is enabled. A value of
>>> 'distinct' means that the path is distinct and disables the above
>>> behaviour. The default value of 'default' defers to an application
>>> wide default specified as a property of ApplicationConfig (this
>>> will default to not enabled).
>>>
>>> - Existing UriInfo methods are not affected, any extension in the
>>> URI is included in the path returned by any of the methods. For
>>> convenience we add UriInfo.getPathExtension() that returns the
>>> extension or null if there isn't one, and
>>> UriInfo.getPlatonicRequestUriBuilder which returns a URI builder
>>> for the request minus the extension. We also add a
>>> UriBuilder.extension(String) that adds the supplied extension to
>>> the current final path segment.
>>>
>>> An example:
>>>
>>> @Path("widgets")
>>> public class WidgetsResource {
>>>
>>> @Context UriInfo uris;
>>>
>>> @GET
>>> @ProduceMime({"application/xml", "application/json")
>>> public WidgetList getWidgets() {
>>> ....
>>> }
>>>
>>> @POST
>>> @ProduceMime({"application/xml", "application/json"})
>>> public Response addWidget(Widget input) {
>>> Widget w = createWidgetEntry(input);
>>> URI platonic = uris.getBaseUriBuilder()
>>> .path(WidgetResource.class)
>>> .build(w.getId());
>>> URI distinct = uris.getBaseUriBuilder()
>>> .path(WidgetResource.class)
>>> .extension(uris.getExtension())
>>> .build(w.getId());
>>> return Response.created(platonic)
>>> .contentLocation(distinct);
>>> }
>>> }
>>>
>>> @Path("widgets/{id}")
>>> public class WidgetResource {
>>> ...
>>> }
>>>
>>> Assume you have an app config that maps "xml" to application/xml
>>> and "json" to application/json. Also assume you have the required
>>> msg body readers and writers for XML and JSON.
>>>
>>> GET /widgets.xml will get you XML, GET /widgets.json will get you
>>> JSON, GET /widgets will get whichever matches your accept header
>>> most closely.
>>>
>>> You can POST XML or JSON to /widgets.xml but you'll always get
>>> back XML. Same for /widgets.json but you'll always get back JSON.
>>>
>>> If you POST to a distinct URI you'll get a platonic location and a
>>> distinct content location. If you post to a platonic you'll get
>>> platonic location and content location (the latter is unfortunate
>>> but a custom message body writer could patch the value once the
>>> format is known.
>>>
>>> Thoughts, comments ?
>>> Marc.
>
> ---------------------------------------------------------------------
> 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.