在遵循 RESTful API 标准的同时,在同一控制器中拥有 getAll、getById 和 getByEmail 的控制器方法 [英] Have controller methods to getAll, getById and getByEmail in the same controller while following RESTful API standards

查看:29
本文介绍了在遵循 RESTful API 标准的同时,在同一控制器中拥有 getAll、getById 和 getByEmail 的控制器方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实体 Users,其中包含 idemailAddress.我想编写一个同时具有 3 个 get 方法的控制器:

I have an entity Users, which contains id and emailAddress. I want to write a controller which has 3 get methods simultaneously:

  • getAll() - http://localhost:8080/api/users?pageNumber=0&pageSize=10
  • get(UUID id) - http://localhost:8080/api/users/209347293875928375928
  • get(String email) - http://localhost:8080/api/users/fireball%40email.comhttp://localhost:8080/api/users?emailAddress=fireball%40email.com"

注意: 两段代码的区别在于最后一个函数的参数不同(第一段是@PathVariable,第二段是@RequestParam.

NOTE: The difference in the two pieces of code is the arguments of the last function in both(The first is @PathVariable and the second is a @RequestParam.

我尝试了两种方法来实现这一点(都遇到了一个单独的问题),第一种是:

I have tried two ways to accomplish this(both run into a separate issue), the first being:

@GetMapping
  @ApiOperation(value = "List all Users")
  @ApiResponses({
    @ApiResponse(code = 200, message = "OK", response = User.class, responseContainer = "List"),
    @ApiResponse(code = 401, message = "Unauthorized", response = Error.class),
    @ApiResponse(code = 404, message = "Not Found", response = Error.class),
    @ApiResponse(code = 500, message = "Internal Server Error", response = Error.class)
  })
  @Transactional(readOnly = true)
  public ResponseEntity<Page<User>> getAll(
      @RequestParam(required = false, defaultValue = "0") int pageNumber,
      @RequestParam(required = false, defaultValue = "10") int pageSize) {
    return ResponseEntity.ok(UserService.getUsers(pageNumber, pageSize));
  }

  @GetMapping(path = "/{id}")
  @ApiOperation(value = "Get User by ID")
  @Transactional(readOnly = true)
  @ApiResponses({
    @ApiResponse(code = 200, message = "OK", response = User.class),
    @ApiResponse(code = 401, message = "Unauthorized", response = Error.class),
    @ApiResponse(code = 404, message = "Not Found", response = Error.class),
    @ApiResponse(code = 500, message = "Internal Server Error", response = Error.class)
  })
  public ResponseEntity<?> get(@PathVariable("id") final UUID id) {

    return UserService.get(id)
        .map(ResponseEntity::ok)
        .map(ResponseEntity.class::cast)
        .orElse(
            ResponseEntity.status(NOT_FOUND).body(new Error(format(USER_NOT_FOUND_MESSAGE, id))));
  }
  
  @GetMapping
  @ApiOperation(value = "Get User by Email Address")
  @Transactional(readOnly = true)
  @ApiResponses({
    @ApiResponse(code = 200, message = "OK", response = User.class),
    @ApiResponse(code = 401, message = "Unauthorized", response = Error.class),
    @ApiResponse(code = 404, message = "Not Found", response = Error.class),
    @ApiResponse(code = 500, message = "Internal Server Error", response = Error.class)
  })
  public ResponseEntity<?> get(@RequestParam("email") final String email) {

    return UserService.get(email)
        .map(ResponseEntity::ok)
        .map(ResponseEntity.class::cast)
        .orElse(
            ResponseEntity.status(NOT_FOUND).body(new Error(format(USER_NOT_FOUND_MESSAGE, email))));
  }

以上在使用 Ambiguous mapping 编译时失败.无法将userController"方法 映射为错误.基本上 getAll()get(@RequestParam("email") final String email) 具有相同的 URL 路径 - /users.

The above fails at compilation with Ambiguous mapping. Cannot map 'userController' method as error. Essentially getAll() and get(@RequestParam("email") final String email) have the same URL path - /users.

第二个是:

  @GetMapping
  @ApiOperation(value = "List all Users")
  @ApiResponses({
    @ApiResponse(code = 200, message = "OK", response = User.class, responseContainer = "List"),
    @ApiResponse(code = 401, message = "Unauthorized", response = Error.class),
    @ApiResponse(code = 404, message = "Not Found", response = Error.class),
    @ApiResponse(code = 500, message = "Internal Server Error", response = Error.class)
  })
  @Transactional(readOnly = true)
  public ResponseEntity<Page<User>> getAll(
      @RequestParam(required = false, defaultValue = "0") int pageNumber,
      @RequestParam(required = false, defaultValue = "10") int pageSize) {
    return ResponseEntity.ok(UserService.getUsers(pageNumber, pageSize));
  }

  @GetMapping(path = "/{id}")
  @ApiOperation(value = "Get User by ID")
  @Transactional(readOnly = true)
  @ApiResponses({
    @ApiResponse(code = 200, message = "OK", response = User.class),
    @ApiResponse(code = 401, message = "Unauthorized", response = Error.class),
    @ApiResponse(code = 404, message = "Not Found", response = Error.class),
    @ApiResponse(code = 500, message = "Internal Server Error", response = Error.class)
  })
  public ResponseEntity<?> get(@PathVariable("id") final UUID id) {

    return UserService.get(id)
        .map(ResponseEntity::ok)
        .map(ResponseEntity.class::cast)
        .orElse(
            ResponseEntity.status(NOT_FOUND).body(new Error(format(USER_NOT_FOUND_MESSAGE, id))));
  }
  
  @GetMapping(path = "/{email}")
  @ApiOperation(value = "Get User by Email Address")
  @Transactional(readOnly = true)
  @ApiResponses({
    @ApiResponse(code = 200, message = "OK", response = User.class),
    @ApiResponse(code = 401, message = "Unauthorized", response = Error.class),
    @ApiResponse(code = 404, message = "Not Found", response = Error.class),
    @ApiResponse(code = 500, message = "Internal Server Error", response = Error.class)
  })
  public ResponseEntity<?> get(@PathVariable("email") final String email) {

    return UserService.get(email)
        .map(ResponseEntity::ok)
        .map(ResponseEntity.class::cast)
        .orElse(
            ResponseEntity.status(NOT_FOUND).body(new Error(format(USER_NOT_FOUND_MESSAGE, email))));
  }

在这里我遇到了控制器无法在 get(@PathVariable("email") final String emailget(@PathVariable("id");) 最终的 UUID id) 带有以下错误:

Here I run into the issue of the controller not being able to resolve between get(@PathVariable("email") final String email and get(@PathVariable("id") final UUID id) with the following error:

Ambiguous handler methods mapped for '/api/gems/users/fireball%40email.com': {public org.springframework.http.ResponseEntity com.personal.project.controllers.UserController.get(java.util.UUID), public org.springframework.http.ResponseEntity com.personal.project.controllers.UserController.get(java.lang.String)}

推荐答案

您可以通过将这两个 Ambiguous 路径合并为一个来解决它.对于第一种情况:

You can solve it by merging these two Ambiguous path into one. For the first case:

  @GetMapping
  @ApiOperation(value = "List all Users")
  @ApiResponses({
    @ApiResponse(code = 200, message = "OK", response = User.class, responseContainer = "List"),
    @ApiResponse(code = 401, message = "Unauthorized", response = Error.class),
    @ApiResponse(code = 404, message = "Not Found", response = Error.class),
    @ApiResponse(code = 500, message = "Internal Server Error", response = Error.class)
  })
  @Transactional(readOnly = true)
  public ResponseEntity<?> getUsers(
      @RequestParam(required = false, defaultValue = "0") int pageNumber,
      @RequestParam(required = false, defaultValue = "10") int pageSize,
// add email as param.
      @RequestParam(required = false) String email,

) {
    if(email ==null || StringUtils.isEmpty(email)){
       return ResponseEntity.ok(UserService.getUsers(pageNumber, pageSize));
    }else return UserService.get(email)
        .map(ResponseEntity::ok)
        .map(ResponseEntity.class::cast)
        .orElse(
            ResponseEntity.status(NOT_FOUND).body(new Error(format(USER_NOT_FOUND_MESSAGE, email))));
  }

对于第二个:

 // change the type UUID id to string.
  @GetMapping(path = "/{id}")
  ...
  public ResponseEntity<?> get(@PathVariable("id") final String id) {
    // check if id as an uuid or email, and based on that take action
  }

这篇关于在遵循 RESTful API 标准的同时,在同一控制器中拥有 getAll、getById 和 getByEmail 的控制器方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆