JAVA EE Rest conditional GET methods on QueryParams - java

I would like to have two GET methods on my Rest resource class.
one would react if query param has value1 and second on value2
Lets say:
#Path("/myApi")
public class MyApiService {
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response methodOne(...) {
...
return ...;
}
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response methodTwo(...) {
...
return ...;
}
How to achieve conditional routing for query params
I would like to methodOne() reacts if QueryParam is ?type=one and methodTwo() if QueryParam is ?type=two

Choosing servlet handlers based on QueryParam is not a good aproach, and by default no library gives you oportunity to do so.
The closest that comes to mind is PathParam, that is something like Path("\api\{param1}\{param2}") but it's not what you are looking for.
To achieve want your want just
unregister those methods as servlet handlers (Optional, if you don't need them outside of queryparam selection scope)
define a new one that will choose based on query param
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response methodThree(QueryParam('type') String type) {
return type.equals("type1") ? this.methodOne() : this.methodTwo();
}

You cannot have two methods with identical parameters for the same path.
It's not pretty, but it will work..
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response myMethod(#QueryParam("type") String type){
if(type.equals("one"))
return methodOne();
else
return methodTwo();
}

Related

Dropwizard Rest API endpoint manipulation

I have a dropwizard application to POST/GET query information. I have a #POST method that populates an arrayList with my query and its' 11 parameters. For brevity, I cut the example down to only show 3 parameters.
#Path("/query")
public class QueryResource
#GET
#Produces(MediaType.APPLICATION_JSON)
#Timed
public List<Query> getQueries() {
List<Query> queries = new ArrayList<Query>();
logger.info("Calling get queries with {} method.");
queries.add(new Query("b622d2c6-03b2-4488-9d5d-46814606e550", "eventTypeThing", "action"));
return queries;
I can send a get request through ARC and it will return successful with a json representation of the query.
I run into issues when I try to make a #GET request on the specific queryId and return a specific parameter of it. As such,
#GET
#Path("/{queryId}/action")
public Response getAction(#PathParam("queryId") String queryId, #PathParam("action") String action){
logger.info("Get action by queryId {}");
String output = "Get action: " + action;
return Response.status(200).entity(output).build();
On the rest client I make a get request to https://localhost/query/b622d2c6-03b2-4488-9d5d-46814606e550/action
I'm expecting that to return the action type of that specific queryId, but instead is returning null.
You did not declare "action" as a proper param in the #Path annotation of the method. You need to change that to:
#Path("/{queryId}/{action}")

how can extract parameter from #QueryParam

#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#Path("/categories")
public Response getAllCategories(#QueryParam(value = "code") String country_code) {
return userService.getAllCategories(country_code);
}
my url:"/user/categories?code=+91"
how can i extracting request parameters "+91" in RESTful web service.
#QueryParam is JAX-RS. If you want to use Spring, the appropriate annotation would be #RequestParam:
public Response getAllCategories(#RequestParam("code") String country_code) {
...
}
But of course, #Path, etc. are also not Spring, so perhaps you should ask yourself if you actually want to use Spring...

Multiple GET methods match: select most specific

I have a web service that looks like:
#Path("/ws")
public class Ws {
#GET public Record getOne(#QueryParam("id") Integer id) { return record(id); }
#GET public List<Record> getAll() { return allRecords(); }
}
The idea is that I can either call:
http://ws:8080/ws?id=1 to get a specific record
http://ws:8080/ws to get all available records
However when I use the second URL, the first #GET method is called with a null id.
Is there a way to achieve what I want without using different paths?
I think this can be achieved with Spring using the #RequestMapping(params={"id"}) and #RequestMapping annotations for the first and second methods respectively but I can't use Spring in that project.
Since the path is the same, you cannot map it to a different method. If you change the path using REST style mapping
#Path("/ws")
public class Ws {
#GET #Path("/{id}") public Response getOne(#PathParam("id") Integer id) { return Response.status(200).entity(record(id)).build(); }
#GET public Response getAll() { return Response.status(200).entity(allRecords()).build(); }
then you should use:
http://ws:8080/ws/1 to get a specific record
http://ws:8080/ws to get all available records

Match empty path parameters in REST

I have a service in rest that looks like:
#GET
#Path("get-policy/{policyNumber}/{endorsement}/{type}")
#Produces(MediaType.APPLICATION_XML)
public String getPolicyIndividual(
#PathParam("policyNumber")String policyNumber,
#PathParam("endorsement")String endorsement,
#PathParam("type")String type){
...
}
And i want to know if there is a way that i can accept every parameter as null value if they are not sent, so if somene makes a call to my service without the params or with not all the params still can match the definition of my service.
Examples:
http://localhost:8080/service/policy/get-policy/
or this:
http://localhost:8080/service/policy/get-policy/5568
or this:
http://localhost:8080/service/policy/get-policy/5568/4
Im well aware that i can define a regex expression like in this answer, but in that case there was only 1 path param defined, what if i have more than one?
That didnt work for me but maybe im doing something wrong, i tried this with no success:
#GET
#Path("get-policy/{policyNumber: .*}/{endorsement: .*}/{type: .*}")
#Produces(MediaType.APPLICATION_XML)
public String getPolicyIndividual(
#PathParam("policyNumber")String policyNumber,
#PathParam("endorsement")String endorsement,
#PathParam("type")String type){
...
}
is the only way to achive this trough a POST? Im using Jersey btw!
You have to create a complete use case scenario for this and call a general method every time if you dont want to write code multiple times.
Say: For an instance use only one parameter passed, then 2 and then all, and none
#GET
#Path("get-policy/{policyNumber: .*}")
#Produces(MediaType.APPLICATION_XML)
public String getPolicyIndividual(
#PathParam("policyNumber")String policyNumber)
{
doSomething(policyNumber, "", "");
}
#GET
#Path("get-policy/{policyNumber: .*}/{endorsement: .*}")
#Produces(MediaType.APPLICATION_XML)
public String getPolicyIndividual(
#PathParam("policyNumber")String policyNumber,
#PathParam("endorsement")String endorsement)
{
doSomething(policyNumber,endorsement, "");
}

Resteasy #path with zero or more path parameters

I am using RESTEasy in my API development. My url is http://localhost:8080/project/player/M or http://localhost:8080/project/player
it means am pasing {gender} as path param.
my problem is how to mapp this url to REST method, i use below mapping
#GET
#Path("player/{gender}")
#Produces("application/json")
but if use it, it maps for http://localhost:8080/project/player/M but not for http://localhost:8080/project/player.
i need a regular expression to map zero or more path parameters
Thanks.
Is there any reason this must be a path parameter and not a query string ? If you change it to use the latter, then you can use a #DefaultValue annotation.
So your code would then look like the following:
#GET
#Path("player") //example: "/player?gender=F"
#Produces("application/json")
public Whatever myMethod(#QueryParam("gender") #DefaultValue("M") final String gender) {
// your implementation here
}
Path parameters (#PathParam) aren't optional. If you want to map;
http://localhost:8080/project/player/M
http://localhost:8080/project/player
You will need two methods. You can use method overloading;
#GET
#Path("player/{gender}")
#Produces("application/json")
public Whatever myMethod(#PathParam("gender") final String gender) {
// your implementation here
}
#GET
#Path("player")
#Produces("application/json")
public Whatever myMethod() {
return myMethod(null);
}
See the below link which has a sample of optional path parameters via regular expressions
RestEasy #Path Question with regular expression
You should use regex when you want have optional parameter in path.
So your code would then look like the following:
#GET
#Path("/player{gender : (/\\w+)?}")
#Produces("application/json;charset=UTF-8")
public Whatever myMethod(#QueryParam("gender") #DefaultValue("M") final String gender) {
// your implementation here
}
For more information see https://docs.jboss.org/resteasy/docs/1.1.GA/userguide/html/Using__Path_and__GET___POST__etc..html

Categories

Resources