搜索相同的资源是常见的场景使用相同的数据类型为PathVariable(例如String).
如果我有一个名为Student的资源,比如:
class Student {
String name;
String email;
...
}
所以,name和email都是字符串
我如何创建两个端点来通过name获取这个学生的信息?或通过电子邮件在春季靴?
我想要这样的东西:
@GetMapping(path="/{name}
public StudentResponse getStudentByName(@PathVariable String name) {...}
和
@GetMapping(path="/{email}
public StudentResponse getStudentByEmail(@PathVariable String email) {...}
,但这会导致歧义端点,因为这两个端点接收相同的参数类型。
在这种情况下如何创建端点?
我假设我的路径必须是不同的,或者它的PathVariable有不同的数据类型避免歧义端点。但是考虑到这种情况很常见,推荐使用什么方法?
不能创建两个端点(student/{email}和student/{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
包含您的有效负载(过滤器,类型,值,名称,电子邮件…)
不能重载path变量(至少不能使用RESTful端点的最佳实践)。它表示资源的标识符(id)。你要做的是一种搜索过滤器。你有两个选项:
-
将查询作为JSON内容提供给POST方法
-
添加查询参数
得到:/学生?name=John Doe
GET:/students?email=john.doe@unknown.com
在这里,很好的讨论了什么时候应该使用查询参数
如果你想使用第二种方法,你可以这样做
@GetMapping(value = "/students", params = { "name" })
public Response getStudentByName(@RequestParam String name) {
//
}
@GetMapping(value = "/students", params = { "email" })
public Response getStudentByEmail(@RequestParam String email) {
//
}