简体   繁体   中英

Multiple endpoints for REST api in springboot

I have two unique keys in a table id , 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 user through userId but use same method for both. Also datatype of id is long and datatype of userId is String in table

So I am trying to do following

the endpoint "/user/{id}" is for userId

@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?

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
   }

}

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM