harv3
harv3

Reputation: 303

Multiple endpoints for REST API in Spring Boot

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

Answers (3)

Vikram Singh Shekhawat
Vikram Singh Shekhawat

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

Jasper Huzen
Jasper Huzen

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

Hassam Abdelillah
Hassam Abdelillah

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

Related Questions