在 RESTful Web 服务中按 ID 和用户名查找

Jul*_*lez 3 java rest spring-mvc restful-url

我很困惑单例资源的最佳偏好是什么。我想要具有用户 ID 的端点:

/users/{id}

但我也想username作为参数:

/users/{username}

我正在使用 Spring MVC(通过 Spring Boot),它说 2 个端点存在冲突。所以我决定首先为用户检索单例资源。但是为了让客户端仍然使用用户名作为参数,我添加了用户名作为用户集合资源的查询参数:

/users?username=<username>

在我repositoryservice层,回报是Optional<User>,即它是emptyor 或one userresult。但是在 中controller,我将其包装在 a 中list,无论是空的还是一个,以使其与/usersas 列表的返回一致。

这是合理的设计吗?或者有没有更好的设计?谢谢。

Ahm*_*yed 5

基本上,您有两种选择:

  • 例如,您可以有两个单独的端点,/users/byId/{id}并且/users/byName/{username}每个端点都映射到不同的控制器方法
class UserController {
    @GetMapping("/byId/{id}")
    Optional<User> findById(@PathVariable("id") String id){
       ...
    }

    @GetMapping("/byName/{username}")
    Optional<User> findByUsername(@PathVariable("username") String username){
       ...
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 或者在一个端点上/users/{id-or-name}进行联合查询,因此:findAllByIdOrName()

我倾向于说在不同的端点上做这件事更干净、更高效。


编辑

RESTful 约定意味着您有 2 个端点:

    @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
       ...
    }
Run Code Online (Sandbox Code Playgroud)

除此之外的任何事情都已经偏离了惯例。