Realistically in REST, path params are never optional.  What you're trying
to do is bind the same service to two different URIs.  This might be a
reason why you want to use sub resources to do the implementation.

Assuming you have some wrapper level around this, adding these two methods
should work.  Note that I've never actually tried this with CXF, but
technically from a spec standpoint this should work fine.

@Path("/")
public class SomeAPI {

@Path("/{tenantId}/someResource")
public SomeResource tenantSomeResource() { // return the resource }

@Path("/someResource")
public SomeResource someResource() { // return the resource }

}

What this says is that the top level SomeAPI class is bound at / (root of
your context) and will serve any request.  It provides two subresources,
one bound at /tenantId/someResource and another at just /someResource which
both provide the same APIs.  Within SomeResource class here you would
provide the implementation of what you're describing, e.g.

public class SomeResource {
@GET @Path("/{id}")
public Response getBySomeId(@PathParam("id") int id, @PathParam("tenantId")
String tenantId)
}

And then tenantId would be null if not found (hopefully, again, never tried
with CXF).

John

On Tue, Jun 23, 2015 at 9:40 PM Kevin Schmidt <ktschm...@gmail.com> wrote:

> That is my fallback plan and isn't that much extra work.  Was just wanting
> to see if JAX-RS had a way to help with it.
>
> On Tue, Jun 23, 2015 at 6:22 PM, Craig McClanahan <craig...@gmail.com>
> wrote:
>
> > I tend to prefer solutions to things like this that will be obviously
> > understood when I pass responsibility for the code on to someone else in
> > the future, especially if that person is (like me) not particularly
> fluent
> > at regexp syntax :-).  How about just going for two resource methods with
> > individual paths (/{tenant}/resource{id} and /resource/{id}) and having
> > them both call a common service method that takes tenant and id
> parameters,
> > and the second one passes null for the tenant?
> >
> > Craig
> >
> >
> > On Tue, Jun 23, 2015 at 5:42 PM, Kevin Schmidt <ktschm...@gmail.com>
> > wrote:
> >
> > > I have a situation where I'd like a @PathParam to be optional.  For
> > example
> > > I'd like for the path /{tenant}/resource/{id} to be matched for both
> > > .../myTenant/resource/12345 and .../resource/12345, the second case
> > passing
> > > in null for the tenant @PathParam.
> > >
> > > I did some research and it seemed like using a regex in my @Path would
> do
> > > the trick, but I've been unable to get it to work.  And in one case,
> I'm
> > > getting behavior that seems to be a bug?
> > >
> > > Here is what I've done:
> > >
> > >     @GET
> > >     @Path("/{tenant : [^/]*}/resource/{id}")
> > >     @Produces({MediaType.APPLICATION_JSON})
> > >     public Response getResource(@PathParam("tenant") String tenant,
> > > @PathParam("id") String id) {
> > > ...
> > >     }
> > >
> > > When I use the above with a URI .../t1/resource/12345 I get tenant=t1
> and
> > > id=12345 as expected, so all is well.
> > >
> > > If I use .../resource/12345 I get a "No operation matching request
> path"
> > in
> > > my log.
> > >
> > > If I use ...//resource/12345 I oddly get tenant=12345 and id=null.
> > >
> > > It is this last case that seems odd, even if my regex in @Path isn't
> > fully
> > > correct, I'd still expect tenant=null and id=12345 in this case.  So is
> > > this a bug?  Or is there an explanation for it?
> > >
> > > But more importantly, is there a regex I can use to have tenant=null
> > when I
> > > use .../resource/12345 and tenant=t1 when I use .../t1/resource/12345?
> > >
> > > FWIW, if I try this @Path:
> > >
> > > @Path("/{tenant : ([^/]*)?}/resource/{id}")
> > >
> > > I get tenant=t1 and id=t1 which also doesn't seem right.  Another bug?
> > >
> > > I'm using CXF as part of Camel 2.15.1 running in Karaf 3.0.x.
> > >
> > > Thanks,
> > >
> > > Kevin
> > >
> >
>

Reply via email to