Springboot - 同一端点上具有相同类型 PathVariable 的两个 GET 请求

Springboot - Two GET request on same endpoint with same type of PathVariable

使用与PathVariable相同的数据类型搜索相同的资源是常见的场景(例如 String).

如果我有名为 Student 的资源,例如:

class Student {
   String name;
   String email;
   ...
}

所以,name 和 email 都是字符串。

我如何创建 2 个端点以通过 nameemail 在 Spring Boot 中获取有关该学生的信息?

我想要这样的东西:

@GetMapping(path="/{name}
public StudentResponse getStudentByName(@PathVariable String name) {...}

@GetMapping(path="/{email}
public StudentResponse getStudentByEmail(@PathVariable String email) {...}

,但这会导致端点不明确,因为这 2 个端点接收相同的参数类型。

在这种情况下我将如何创建端点?

我假设我的路径必须不同或具有不同的 PathVariable 数据类型以避免端点不明确。但是鉴于这种情况很常见,推荐的方法是什么?

您不能重载路径变量(至少不能使用 RESTful end-points 的最佳实践)。这意味着资源的标识符 (id)。您正在尝试做的是一种搜索过滤器。您有 2 个选择:

  1. 添加查询参数

    获取:/students?name=李四
    获取:/students?email=john.doe@unknown.com

这里,a good discussion when you should use query parameters

如果你想使用第二种方法,你可以这样做

@GetMapping(value = "/students", params = { "name" })
 public Response getStudentByName(@RequestParam String name) {
   //
 }

@GetMapping(value = "/students", params = { "email" })
public Response getStudentByEmail(@RequestParam String email) {
  //
}

您不能像这样创建两个端点(学生/{email} 和学生/{name}) 我建议 3 种方法:

1- 使用两个端点 student/email/{email}student/name/{name}

2- 使用 @RequestParam 以使用 GET 端点查询参数: student/filter?name=n&email=e

3- 使用这个概念两个查询参数,一个确定你想要的字段,第二个代表值: 然后调用 GET student/filter?field=name&value=somename

@GetMapping(path="/filter")
public StudentResponse getStudentByFeild(@RequestParam String field, @RequestParam String value)
{
   // TODO: if or switch statement on the field value ("name", "email", ...)
   // Example Student s = ("name".equals(field)) ? stdService.findByName(value) : stdService.findByEmail(value)
   // Or switch(field): case "name": service.getByName(value); break; ...
}

4- 将 POST 与 @RequestBody 一起使用,其中包含您的有效负载(过滤器、类型、值、名称、电子邮件...)