How to write single JAX-RS resource for variable number of path parameters
Asked Answered
I

1

7

I have been writing a JAX-RS based ReST application using Apache Wink and I understood the concept of association between path params to resource handle class. Here I see that, We can define paths using @Path annotation and corresponding resource which will get called based on HTTP Method..

Now I am looking at something like a resource which should get called for variable number of path parameters.

For example I want my single resource class CollegeResource should be called for URIs like /rest/college, /rest/college/subject, /rest/college/subject/teachers, and it can go up to any number of path parameters.

If I know the number of path params in prior then I could have achieved this using something like this /rest/college/{param1}/{param2}. But number of path params is unknown. So I felt (I may be wrong) can not use this approach.

One more way I could still use is using query parameters. But I want this to be available to be as path params only.

Is there any way to get this done using apache wink with any other configuration ? If not in Apache wink, any other JAX-RS implementaions support this ?

Impulse answered 12/3, 2015 at 16:7 Comment(0)
R
10

You can use a regex, like @Path("/college/{param: .*}"), then use List<PathSegment> as a method parameter. For example

@GET
@Path("/college/{params: .*}")
public Response get(@PathParam("params") List<PathSegment> params) {
    StringBuilder builder = new StringBuilder();
    for (PathSegment seg: params) {
        builder.append(seg.getPath());
    }
    return Response.ok(builder.toString()).build();
}

C:\>curl -v http://localhost:8080/college/blah/hello/world/cool
Result: blahhelloworldcool

But personally, I would stay away from this kind of thing. Your URI paths (templates) should have some semantic meaning. Allowing an arbitrary number of path params, that may not have any meaning, is error prone, and IMO, is a cause for redesign. I would need to know the semantics behind this design choice before I can offer any advice though.

Ruby answered 13/3, 2015 at 1:15 Comment(5)
I am looking at, when I'm invoking RDBMS, I will send 3 objects (databasename, schema name &table name) in the path params. My URL will be like /api/database/dbname/schemaName/tablename. But while I'm invoking Salesforce.com I will send only one SFDC object, and my URL will be /api/sfdc/Account. Here I don't want to have multiple resource for each target application. So I want to have single resource with base URI /api/{targetAppName} and this can have any number of path params. I can access {targetAppName} in code & decide the target application and do things accordingly.Impulse
And you want only one resource method to handle all possible use cases? If that's what you want, then go for itRuby
Works. Final say for this thread would be, by using {params: .*}, we can make it generic.Impulse
there is no reason to "stay away form this", if you're using it in a manner that maintains the spirit of REST. imagine a service that federates objects (data, executable code, rel-links, etc.) in a pub/sub manner. i can push code to a URI, and then that URI becomes a reference to that runnable instance (think Lambda) that is addressable in a federation.Levanter
@PaulSamsotha One possible use-case I can think of here is as a mock service. We can make use of this strategy to implement an excellent simulator for any non-available (readily) service end-points with corresponding request-response mapping in DB (may be).Pruett

© 2022 - 2024 — McMap. All rights reserved.