[jax-rs-spec users] Re: Getting full path template after sub-resource locators

From: Ron Dagostino <>
Date: Wed, 17 Feb 2016 10:50:11 -0500

Thanks for the feedback, Marek. Here is our use case.

We annotate our resource methods with @RolesAllowed to identify the roles
that can invoke them. The listed roles correspond to role names in our
role-based access control repository (RBAC), and we make the authz decision
in a post-match ContainerRequestFilter. The filter verifies an incoming
signed OAuth bearer token and extracts the set of active roles in the token
from a claim. The filter then decides to accept or reject the request
based on whether or not there is an intersection between the active roles
in the token claim and the roles listed in the @RolesAllowed annotation.
This works great, but we have an audit/compliance requirement to be able to
clearly identify which roles are allowed to invoke which APIs, and we are
now deciding how to meet this requirement. Our thought is that the APIs
can be identified at runtime by their method and full template path. For

We would be able to identify at runtime the following two facts:

FooRole is able to invoke "GET root/foo={value}"
IdsRole is able to invoke "GET root/id1={id1Value}/id2={id2Value}"

If we have these code definitions:

@Path("root") // resource class
public class Root {
    @Path("foo={value}") // sub-resource method
    @RolesAllowed("FooRole") // token/RBAC authnz
    public String get() {
        return "foo";

    @Path("id1={id1Value}") // sub-resource locator
    public SubResource getSubResource() {
        return new SubResource();

public class SubResource {
    @GET // sub-resource method
    @RolesAllowed("IdsRole") // token/RBAC authz
    public String get() {
        return "ids";

It makes sense to report the full template path rather than the URL because
every URL is different (root/foo=1, root/foo=abc, etc.) but the full
template path is the same for every matching URL (root/foo={value}).

The current 2.0 API does not support (easily, without re-implementing stage
3 of the matching algorithm) identifying the full path template when
sub-resource locators are involved.

Using the full path template is not the only approach. We could require
the use of an additional annotation to explicitly provide an API method
identifier, or we could use java.lang.reflect.Method.toGenericString() to
identify the API method name. So there are workarounds. But the best
solution to us at this time seems to be to always report something of the
form "<HTTPMETHOD> <full/{template}/path>" -- it is API-friendly because
everybody thinks in terms of methods and paths, and the information is
there already; we are just looking for an API to get at it.

Is this something a lot of people would want to do? I don't know. There
was a reason for including UriInfo.getMatchingResources() and
UriInfo.getPathParameters(); I don't know what the reason was, but the use
case I describe requires a more complete exposure of the kind of
information that these methods already provide.


On Wed, Feb 17, 2016 at 10:01 AM, Marek Potociar <>

> Hi Ron,
> I think you really need to first make case why is it important to expose
> API for constructing a full path template. We need to understand how many
> people would benefit from such API, before we can consider adding it to the
> spec.
> Cheers,
> Marek
> On 17 Feb 2016, at 03:01, Ron Dagostino <> wrote:
> Hi again. I have concluded that it is not possible to construct the full
> path template for a request without (re-)implementing a significant portion
> of the matching algorithm (specifically, stage 3). The problem is that
> UriInfo does not provide a complete picture of what happened during the
> matching process -- it does not specify which methods were matched on
> instances generated by sub-resource locators. It provides the instances,
> but it does not provide the matched methods.
> Assuming it is agreed to be reasonable to want to know the full path
> template for a request (I can explain why I want to do this if necessary),
> and assuming I am not missing anything and it is indeed not (easily)
> possible with the 2.0 API, and simple solution would be to add a method to
> UriInfo that returns the matched methods as shown in the sample Javadoc
> below. A more complete solution would be to expose the entire match model:
> a list with each element being an object that contained a resource method,
> a path parameters map (empty if no template substitutions were made), and
> the matched resource.
> I am hoping for some feedback on this.
> Ron
> java.lang.List<java.lang.reflect.Method> *getMatchedMethods*()
> Get a read-only list of the currently matched resource methods. Each entry
> is a resource method that matched the request URI either directly or via a
> sub-resource method or a sub-resource locator. Entries are ordered
> according to reverse request URI matching order, with the current resource
> method first. E.g. given the following resource classes:
> @Path("foo")
> public class FooResource {
> @GET
> public String getFoo() {...}
> @Path("bar")
> public BarResource getBarResource() {...}
> }
> public class BarResource {
> @GET
> public String getBar() {...}
> }
> The values returned by this method based on request uri and where the
> method is called from are:
> RequestCalled fromValue(s)
> GET /foo FooResource.getFoo FooResource.getFoo
> GET /foo/bar FooResource.getBarResource FooResource.getBarResource
> GET /foo/bar BarResource.getBar BarResource.getBar,
> FooResource.getBarResource
> RequestCalled fromValue(s)
> GET /foo RequestContextFilter (pre-match) null
> GET /foo
> RequestContextFilter (post-match)
> FooResource.getFoo
> GET /foo/bar
> RequestContextFilter (post-match)
> BarResource.getBar, FooResource.getBarResource
> *Returns:*a read-only list of matched resource methods.
> On Mon, Feb 15, 2016 at 9:55 PM, Ron Dagostino <> wrote:
>> Hi everyone. I want to write a ContainerRequestFilter that can generate
>> the full path template value "root/id1={id1Value}/id2={id2Value}" for the
>> following case and also generate correct full path template values in the
>> general case. I don't think it can be reliably done when sub-resource
>> locators are involved. For example, given these classes:
>> @Path("root") // resource class
>> public class Root {
>> @Path("id1={id1Value}") // sub-resource locator
>> public SubResource getSubResource() {
>> return new SubResource();
>> }
>> }
>> public class SubResource {
>> @Path("id2={id2Value}")
>> @GET // sub-resource method
>> public String get() {
>> return "the entity";
>> }
>> }
>> And given this request:
>> /root/id1=2/id2=2
>> The problem is that uriInfo.getPathParameters() returns this
>> MultiValuedMap in the filter:
>> {id2Value=[2], id1Value=[2]}
>> There is no way I can reliably get from "/root/id1=2/id2=2" to
>> "root/id1={id1Value}/id2={id2Value}" given the MultiValuesMap contents.
>> Basically I think there is no way to reliably know what the full path
>> template value is for a request when sub-resource locators are involved.
>> Is this true?
>> Ron