Reputation: 303
I have two unique keys in a table: id
and userId
. I have to create a REST API in Spring to get user details if any of the two keys are given as path variables.
The challenge here is we have to create two different endpoints for getting user through id
and getting a user through userId
, but use same method for both. Also datatype of id
is long
and datatype of userId
is String
in my table.
So I am trying to do the following:
@RequestMapping(value = {"/{id}","/user/{id}"}, method=RequestMethod.GET)
public response getUser(@PathVariable("id") String id) {
}
But I am unable to figure out how to check whether I got id
or userId
inside the method. Also is this the right way to do it?
Upvotes: 10
Views: 19331
Reputation: 764
You can do this with single method like this:
@RequestMapping(value = {"/{id}", "/user/{userId}"}, method = RequestMethod.GET)
public void getUser(@PathVariable(value = "id", required = false) String id,
@PathVariable(value = "userId", required = false) Long userId) {
if (id != null) {
//TODO stuff for id
}
if (userId != null) {
//TODO stuff for userId
}
}
Upvotes: 15
Reputation: 1573
Aren't you able to refactor the database to have only one id? That makes things clear and keeps the code cleaner.
If that is not possible you can create 2 methods with meaningful names.
// handles: /user/{entityId}
@RequestMapping(value = "/user/{entityId}", method=RequestMethod.GET)
public UserDto getUserByEntityId(@PathVariable("entityId") long entityId){
// call service
}
// handles: /user?userId={userId}
@RequestMapping(value = "/user", method=RequestMethod.GET)
public UserDto getUserByUserId(@RequestParam("userId", required=true) String userId){
// call service
}
You can discuss about about the correct names/signatures of the methods.
Another advantages of this approach is that you are able to add Swagger doc annotations to each of them.
Upvotes: 1
Reputation: 2294
I would use the @RequestMapping
Multiple paths mapped to the same controller method possibility in such a manner.
I suspect that even if you refactor your code to call one single method, you still have to implement some logic to differentiate between the two parameters inside the controller method.
Besides, getUserById()
signature is ambiguous. What the parameter id
means the id
or userId
Having two separate method for what you want to acheive would be more efficient two handle each case properly. Inside each controller method you can use a common logic for the two if you want.
@RequestMapping(value = "/user/{userId}", method=RequestMethod.GET)
public String getUserById(@PathVariable("userId") String userId){
// Common login
}
@RequestMapping(value = "/id", method=RequestMethod.GET)
public String getUserByUserId(@PathVariable("userId") String userId){
// Common login
}
You can even implement for each endpoint validators to check either you @PathVariable is valid or not in case of Long
or String
Here are some references ref1, ref2
Upvotes: 1