Reputation: 2094
I am trying to follow Rest Principles, so I have two rest controllers
with a base URL localhost:8088/trucks
.
First, I have to get all trucks:
@GetMapping(value = "/trucks")
public final Collection<TruckDto> getAllTrucks() {
LOGGER.debug("test: getAllTrucks()");
Collection<Truck> trucks = truckService.getAllTrucks();
return mappingService.map(trucks, TruckDto.class);
}
Note, my issue also has to do with the fact that I have different classes I am returning for truckById
and truckByTruckCode
.
And I have 'get truck by ID' service:
@GetMapping(value = "/trucks/{truckId:[0-9]+}")
@ResponseStatus(HttpStatus.FOUND)
@ResponseBody
public final TruckDto getTruckId(@PathVariable(value = "truckId") final Integer truckId) {
LOGGER.debug("test: truckId({})", truckId);
Truck truck = truckService.getTruckById(truckId);
return mappingService.map(truck, TruckDto.class);
}
Now I have a get by truckCode that works but it doesnt follow the rest principle , which is something like , there should be only one base url and all others build from it , here it is
@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping(value = "/trucks/{truckCode:[0-9]*[a-zA-Z][a-zA-Z0-9]*}")
public final TruckWithAvgPetrolDto getTruckByTruckCode (@PathVariable(value = "truckCode")
final String truckCode) {
LOGGER.debug("getTruckByTruckCode()");
TruckWithAvgDto truck = truckService.getTruckByTruckCode(truckCode);
return mappingService.map(truck, TruckWithAvgPetrolDto.class);
}
Now it works but I think it should be an optional param there for it should be in one method. So maybe I can have some sort of optional return type because I have two different services, methods to return in both situations.
Because get by id
just gets truck detail, but get by trukCode
performs a left join and gets truck average consumption of petrol from an order table so I have two different DTOs for get by id
and get by truckCode
.
My questions are how can I get something like one method say getBY(param)
if I put a number it should get by id and return TruckDto
but if I put a code like BY788 it should get by code and return a TruckWithAvgPetrolDto. Is that's possible?
Upvotes: 1
Views: 81
Reputation: 2094
This is a solution that works but i will need verification that it is ok to do such in rest or it is bad practice
@GetMapping("/trucks/{value}")
public ResponseEntity<?> getTruckByIdOrCode(@PathVariable(value = "value" )String value) {
if (value.matches("[0-9]*[a-zA-Z][a-zA-Z0-9]*")) {
TruckWithAvgDto list = truckService.getTruckByTruckCode(value);
return new ResponseEntity<TruckWithAvgDto>(list, HttpStatus.FOUND);
}else {
Truck truck = truckService.getTruckById(Integer.parseInt(value));
return new ResponseEntity<Truck>(truck,HttpStatus.FOUND);
}
}
Upvotes: 1