I'm struggling to find a solution for this... I would like to know how to get a specified parameter passing it through the request without having to code each specific case in Spring Boot API.
For example, in my case I have this JSON object:
{
"id": 3,
"name": "test",
"dominio": "dom",
"altas": "6",
"bajas": "2",
"default_group": [
{
"idRef": 1,
"name": "Users",
"path": "OU=es"
}
],
"office": [
{
"idRef": 1,
"title": "Intern",
"name": "CN=Office license",
"path": "OU=licenseOffice"
},
{
"idRef": 2,
"title": "Specialist",
"name": "CN=Office License F3",
"path": "OU=LicenseGroupF"
}
]
Apart from this, I have all the entities defined in my code, but I would like to access one of their parameters just using their names, like name, dominio, altas, bajas, default_group or office.
The idea is to do this without having to code each method for each parameter.
I wouldn't have to do this for the nested objects (office and default_group) just getting the info from them passing the name of the parameter.
So I would like to do something like:
GET --> localhost:8080/api/3/name
And this would return the name of object with id 3
Or doing this:
GET --> localhost:8080/api/3/default_group
And this would return the Array containing all the default_groups inside.
Apart from this, I would like to know if is it possible to do a PUT request for the methods doing the same thing.
I don't know if this can be done, but in case that it can, would it be possible for you to give some guidance or something...
Thank you very much
Edit. Thanks to @daniu I made it work flawlessly, I paste my solution here based on his comment so if anybody find it helpful. My object is called "Compania".
@GetMapping("/{companiaId}/{field_name}")
public Object queryField(
@PathVariable("companiaId") Long companiaId,
@PathVariable("field_name") String fieldName) {
Map<String, Function<Compania, Object>> fieldRetrievers = Map.of(
"name", Compania::getName,
"dominio", Compania::getDominio,
"altas", Compania::getAltas,
"bajas", Compania::getBajas,
"default_group", Compania::getDefault_group,
"office", Compania::getOffice
);
Compania c = companiaService.getCompaniaNotOpt(companiaId);
Function<Compania, Object> retriever = fieldRetrievers.get(fieldName);
return retriever.apply(c);
}
getCompaniaNotOpt is a method that takes a Compania without being Optional, so it works.
Thanks daniu.
CodePudding user response:
I wouldn't consider this the cleanest of designs, but what would work is creating a Map
that contains all the field accessors by name:
Map<String, Function<YourClass>> fieldRetrievers = Map.of(
"name", YourClass::getName,
"default_group", YourClass::getDefaultGroup,
"office", YourClass::getOffice
);
Then you can use that in your controller (service actually, but to keep it short here):
@GetMapping("/path/{field_name}")
Object queryField(@PathVariable("field_name") String fieldName) {
YourClass c = getObject();
Function<YourClass, Object> retriever = fieldRetrievers.get(fieldName);
return retriever.apply(c);
}