Lokesh Cherukuri Lokesh Cherukuri - 19 days ago 8
Java Question

Spring REST @RequestMapping practices

@RestController
@RequestMapping(value = "/players")
public class REST {

@RequestMapping(method = RequestMethod.GET)
public List<Player> getAll() {
return service.getAll();
}

@RequestMapping(method = RequestMethod.GET, params = {"team", "score"})
public List<Player> getByPlayerAndScore(@RequestParam(value = "team") String team,
@RequestParam(value = "score", required = false) int score) {
return service.getByPlayerAndScore(team, score);
}
}


Q1: I am expecting first method to work for url "/players" (worked as expected) and second method to work for url's ("/players?team=xyz", "/players?team=xyz&score=1000"). spring used method1 for "/players?team=xyz". Even i specified score as optional, unless i specify 2 params, spring is is not using 2nd method. How to solve this and what is best way of writing controller methods to handle these type of requests where user can send different sets of available params (like param1&param2, only param1, only param2 etc).

Q2: For the 2nd type of query with different sets of params, how to write database queries in DAO layer. should i write separate methods each with a different query or one method with multiple if statements(like if user sent 'team' add team to DB query, if user sent 'score' add it to DB query ...)

Answer

Your second mapping explicitly specifies that both the team and score request parameters must be present, and they aren't in your example of /players?team=xyz. The fact that you wrote required = false on the binding for the method parameter is irrelevant--the @RequestMapping explicitly says that the parameter must be present in the request. (Note that you can have a parameter but no value, as in the common Spring Security URL of /login?error. This would match params = { "error" } but would have no value.)

It might be simpler to use a regular if statement in a single controller method.

Alternately, you may want to look into Spring's Querydsl integration, which allows you to interpret query parameters as a Predicate that can be passed directly to a Spring Data finder method.

Also, look into the new composite convenience annotations such as @GetMapping, which will make your code a bit simpler to read.