It is common scenario to search same resource using same data type as PathVariable (for example String).
If I had resource named Student like:
class Student {
String name;
String email;
...
}
So, both name and email are Strings.
How would I create 2 endpoints to get information about this student by name or by email in Spring Boot?
I would like to have something like this:
@GetMapping(path="/{name}
public StudentResponse getStudentByName(@PathVariable String name) {...}
and
@GetMapping(path="/{email}
public StudentResponse getStudentByEmail(@PathVariable String email) {...}
, but this leads to ambiguous endpoint since these 2 endpoints receive same parameter types.
How would I create endpoints in such case?
I assume my path would have to be different or to have different data types of its PathVariable to avoid ambiguous endpoint. But given that this scenario is quite common case, what is recommended way to do it?
CodePudding user response:
You can't create two endpoints like that (student/{email} and student/{name}) I suggest 3 methods:
1- use tow endpoints student/email/{email}
and student/name/{name}
2- use @RequestParam
to use to query param with your GET endpoint :
student/filter?name=n&email=e
3- use this conception two query params one to determine which field you want, the second one represents the value:
Then call 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- use POST with @RequestBody
that contains your payload (filter, type, values, name, email ...)
CodePudding user response:
You can't overload the path variable (at least not with best practices of RESTful end-points). That is meant for the identifier (id) of the resource. What you are trying to do is kind of a search filter. You have 2 options:
Add query parameter
GET: /students?name=John Doe
GET: /[email protected]
Here, a good discussion when you should use query parameters
If you want to use the 2nd approach, you could do something like this
@GetMapping(value = "/students", params = { "name" })
public Response getStudentByName(@RequestParam String name) {
//
}
@GetMapping(value = "/students", params = { "email" })
public Response getStudentByEmail(@RequestParam String email) {
//
}