Issue
Suppose I have this controller mapping function:
@GetMapping("/result")
public Stats result(@RequestParam Integer homeId, @RequestParam Integer awayId)
throws MissingTeamException, InvalidTeamIdExcpetion {
//Validation starts here
int numOfAvailableTeams = teamResource.retrieveAllTeams().size();
if( homeId < 0 || homeId >= numOfAvailableTeams)
throw new InvalidTeamIdExcpetion(homeId);
if(awayId < 0 || awayId >= numOfAvailableTeams)
throw new InvalidTeamIdExcpetion(awayId);
//end of validation
return generateResult(homeId, awayId);
}
You can see that I am validating the home and away ids.
Can I do a it in a cleaner way apart of creating a custom validator class?
Solution
Generally in every case logic should be wrote in service class (marked by @Service
), not in controller. So, you can create a service class with method validating()
with arguments needed to validate. Service example:
@Service
public class YourService {
//This variable and constructor are optional because I didn't see your whole code.
//But if you will to create TeamResource field in service, Spring Boot will automatically
//inject teamResource if you have suitable Bean.
private TeamResource teamResource;
public YourService(TeamResource teamResource) {
this.teamResource = teamResource;
}
public TypeOfMethodGenerateResult validate(Integer homeId, Integer awayId) {
int numOfAvailableTeams = teamResource.retrieveAllTeams().size();
if (homeId < 0 || homeId >= numOfAvailableTeams)
throw new InvalidTeamIdExcpetion(homeId);
if(awayId < 0 || awayId >= numOfAvailableTeams)
throw new InvalidTeamIdExcpetion(awayId);
return generateResult(homeId, awayId);
}
}
And controller:
//Autoinject like in service.
private YourService yourService;
public YourService(YourService yourService) {
this.yourService = yourService;
}
@GetMapping("/result")
public Stats result(@RequestParam Integer homeId, @RequestParam Integer awayId)
throws MissingTeamException, InvalidTeamIdExcpetion {
return yourService.validate(homeId, awayId);
}
Answered By - fr3ddie