Currently, some of our query-related APIs and Controllers are:
[GET] api/study-group?sortby=latest
[GET] api/study-group?sortby=star
[GET] api/study-group?sortby=level
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/study-group")
public class StudyGroupController {
private final StudyGroupService studyGroupService;
@GetMapping
public ResponseEntity<List<StudyGroupResponseDTO>> findStudyGroup(
@RequestParam(name = "sortby", defaultValue = "createdat") String sortBy) {
studyGroupService.findAll(sortBy);
......
}
}
It handles the logic for the controller, but I wonder what kind of method would be better for branching processing for the sorting method.
The first method is branch processing through the if statement.
@Service
@RequiredArgsConstructor
public class StudyGroupService {
public List<StudyGroupResponseDTO> findAll(String sortBy) {
if(sortBy.equals("star") {
searchStudyOrderByStar()l
}else if(sortBy.equals("...")) {
....
}else {
...
}
}
private List<StudyGroupResponseDTO> sort(Function<StudyGroup, Comparable> function) {
return studyGroupRepository
.findAll()
.stream()
.sorted(Comparator.comparing(function, Comparator.reverseOrder())
.thenComparing(StudyGroup::getSeason, Comparator.reverseOrder()))
.map(studyGroupMapper::toResponseDTO)
.collect(Collectors.toList());
}
private List<StudyGroupResponseDTO> searchStudyOrderByCreatedAt() {
return sort(studyJournalService::searchLatestJournalCreatedAt);
}
private List<StudyGroupResponseDTO> searchStudyOrderByStar()
return sort(studyGroup -> studyGroup.getJournals().size());
}
private List<StudyGroupResponseDTO> searchStudyOrderByLike() {
return sort(StudyGroup::getLike);
}
}
Of course, I'm also thinking of using Enum instead of String. However, even if it is changed, setting a branch with an if statement does not seem to change.
Another way to think about it is to use Map.
@Service
@RequiredArgsConstructor
public class StudyGroupService {
private final Map<String, Function<StudyGroup, Comparable> sortMap;
public List<StudyGroupResponseDTO> findAll(String sortBy) {
sortMap.get(sortBy);
....
}
}
Which method do you think looks best?
Or is there a better way than the ones listed above??
If you have any good comments, we would appreciate your feedback!
CodePudding user response:
You can use springs' GetMapping.params() to specify mapping to be invoked for certain request parameter value to get rid of if-else
construct entirely. It's an alias for RequestMapping.params().
The parameters of the mapped request, narrowing the primary mapping. Same format for any environment: a sequence of "myParam=myValue" style expressions, with a request only mapped if each such parameter is found to have the given value.
Then you would need to define additional mapping for each possible value of the paramater, spring will take care of invoking correct mapping, depending on the value of sortby
.
@GetMapping(params = "sortby=latest")
public ResponseEntity<List<StudyGroupResponseDTO>> findStudyGroupSortByLatest() {
//logic for sort by latest
}
@GetMapping(params = "sortby=star")
public ResponseEntity<List<StudyGroupResponseDTO>> findStudyGroupSortByStar() {
//logic for sort by star
}