users@jsr311.java.net

Re: JAX-RS: UriBuilder.fromResource treats templates differently

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Mon, 07 Jul 2008 05:46:56 -0400

On Jul 6, 2008, at 7:19 PM, Manger, James H wrote:
> A specific design choice in draft-gregorio-uritemplate-03 is to
> prevent any <reserved> chars coming from a parameter value. All URI
> structure (ie <reserved> chars) is controlled by the template
> author, not the party providing the parameter values. <reserved>
> chars in parameter values are always %-escaped. UriBuilder, in
> contrast, %-escapes much less (just ? and # in paths, I think; not
> sure what elsewhere).
> The 18 <reserved> chars are : / ? # [ ] @ ! $ & ‘ ( ) * + , ; =
>
> SOLUTION
>
> I don’t have a nice, quick, easy solution.
>
> My preference would be for UriBuilder to support an Internet URI
> template spec once such a thing is finalized.
> That point is not close enough for JAX-RS so I think UriBuilder
> should only try to support the most basic templates that will
> (almost) certainly be compatible with a future URI template spec.
>
That is the direction we have been following so far. limited=false is
there to accommodate multi-segment path variables which seems like a
common enough use case to justify the divergence.

> My suggestion:
> • UriBuilder should accept templates with {name} placeholders.

This is the status quo.

> • Each placeholder is replaced with the corresponding parameter
> value after %-escaping all non-<unreserved> characters in that value
I could live with this additional restriction. Its not quite as
flexible but as the current formulation but it wouldn't prevent any
URI being built.


> (or replaced by an empty string if the parameter is not defined).

That is currently an error and I think it should stay that way.

> UriBuilder.isEncoded() does NOT apply to parameters passed to
> UriBuilder.build() – they always get encoded.

I don't think that is necessary.


> • The name in {name} should be a valid Java identifier (or an
> identifier as defined in Unicode annex #31 “Identifier and Pattern
> syntax” http://www.unicode.org/reports/tr31/ ).

The former isn't far from where we are now.

> Future versions of JAX-RS may give special meaning to other names,
> though implementations of this version of JAX-RS must treat them all
> the same.

Current versions should flag an error for invalid names so an attempt
to use an incompatible future template with a 1.0 implementation won't
silently cause an application to break.

> Now the hard part, what to do with unlimited (or :regex)
> placeholders from @Path values. Three options (from most preferred
> to least):
> • Scrap the UriBuilder.fromResource(Class) and
> UriBuilder.path(Class/Method) methods – admitting that parsing and
> building (though related) are too awkward to unite in a single
> syntax. Code can still call
>
> UriBuilder
> .fromPath(FooResource.class.getAnnotation(Path.class).value());
> if it really wants.

I don't like this, building URIs to resources seems like a pretty
common use case and making it harder doesn't in the way you suggest is
a step backwards.

> • UriBuilder explicitly states that when it accepts @Path values,
> it totally ignores the limited=false attribute (or:regex component).

That's possible.

> • Something more complicated.
>
Optional validation ? Seem like that could be useful during
development at least.


> A URI template spec is likely to allow a placeholder to expand into
> multiple path segments (like an unlimited @Path placeholder) – but
> only if each segment is passed as a separate string (eg { “123”,
> “abc” } -> “123/abc”; while “123/abc” -> “123%2Fabc”). Consequently,
> the following method would be useful:
> UriBuilder.build(MultivaluedMap<String,Object> values)
> It would be a bit strange to define such a method before UriBuilder
> supports templates sophisticated enough to indicate how multiple
> values are handled.

Agreed.

> Would it cause any hassles if adding this method was deferred to a
> future version of the spec (given that UriBuilder is an abstract
> class, not an interface)?
>
Adding new methods to an abstract class in future versions is fine.

Marc.

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