Search code examples
javarestspring-mvcrestful-url

FInd by ID and Username in RESTful Web Services


I'm confused as what is the best preference for singleton resource. I want to have endpoint which has user id as:

/users/{id}

But I also want username as parameter:

/users/{username}

I'm using Spring MVC (via Spring Boot) and it says the 2 endpoints are in conflict. So I decided to the first for retrieving singleton resource for users. But in order for the client to still use username as parameter, I added username as query parameter for the collection resource of users:

/users?username=<username>

In my repository and service layers, the return is Optional<User>, i.e. it's either empty or one user result. But in the controller, I wrap this in a list, either empty or one, to make it consistent with the return of /users as list.

Is this reasonable design? or is there any better design? Thanks.


Solution

  • Basically, you have two options:

    • You either have two separate endpoints, for example, /users/byId/{id} and /users/byName/{username} each mapped to a different controller method
    class UserController {
        @GetMapping("/byId/{id}")
        Optional<User> findById(@PathVariable("id") String id){
           ...
        }
    
        @GetMapping("/byName/{username}")
        Optional<User> findByUsername(@PathVariable("username") String username){
           ...
        }
    }
    
    • Or one endpoint /users/{id-or-name} and you make the union query, so: findAllByIdOrName()

    I tend to say that it's cleaner and more efficient to do it in separate endpoints.


    Edit

    The RESTful convention would mean that you have 2 endpoints:

        @GetMapping("/{id}")
        Optional<User> findById(@PathVariable("id") String id){
           ...
        }
    
        @GetMapping("/")
        List<User> findUsers(@RequestParam("username") String username){
           // if username is not empty, filter users
           // we could also filter with other user properties according to specs
           ...
        }
    

    Anything other than such would be already deviating from the conventions.