-
String으로 사용되던 데이터 enum으로 상수처리운영 중인 서비스/Coconut. 2024. 1. 30. 18:15
빠르게 만든다는 핑계로 String으로 받아서 처리하던 값들을 enum으로 변경하려고 합니다.
게시글 작성에서 사용되는 카테고리와 게시글 정렬기준이 되는 값들을 프론트엔드와 상의하여 정리하였습니다.
1. Setter를 사용해서 enum 할당
게시글 목록을 조회할 때 사용하는 DTO입니다.
sortBy 항목을 String으로 받고 있는데 굉장히 위험한 느낌입니다.
orderBy도 마찬가지입니다. 모두 enum을 사용해서 상수처리 해보겠습니다.
@Data @ToString @Slf4j @NoArgsConstructor @AllArgsConstructor public class ListReqDto { @Schema(description = "페이지 (1부터 시작)", example = "1") @Min(value = 1, message = "page는 최소 1 이상이어야 합니다.") private int page = 1; @Schema(description = "페이지 사이즈", example = "10") @Min(value = 1, message = "size 최소 1 이상이어야 합니다.") private int size = 10; @Schema(description = "정렬 기준", example = "createdAt") private String sortBy = "createdAt"; @Schema(description = "오름차순/내림차순", example = "asc/desc") private String orderBy = "desc"; // NOTE: 프론트에서는 page가 1부터 시작하고 있어서 서버에서 -1을 합니다. public Pageable toPageable () { int page = this.page - 1; int size = this.size; Sort sort = this.orderBy.equals("desc") ? Sort.by(this.sortBy).descending() : Sort.by(this.sortBy).ascending(); return PageRequest.of(page, size, sort); } }
enum을 사용해서 상수로 정의하겠습니다.
먼저 정렬기준입니다.
public enum SortBy { POPULAR("popular", "viewCount"), RECENT("recent", "createdAt"); private final String fieldName; private final String sort; SortBy (String sort, String fieldName) { this.sort = sort.toLowerCase(); this.fieldName = fieldName; } public String getSort() { return sort; } public String getFieldName() { return fieldName; } public static SortBy match(String sort) { return Arrays.stream(SortBy.values()) .filter(sortBy -> sortBy.getSort().equalsIgnoreCase(sort)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("정의되지 않은 정렬 기준입니다.: " + sort)); } }
Enum
생성자에 들어가는 인자 만큼 enum의 상수값에 설정 가능합니다.
위에서는 sort와 fieldName 두가지를 사용하고 있습니다.
match라는 static 메소드를 사용해서 매칭되는 enum값을 반환할 수 있도록 구현하였습니다.
enum.values()는 enum[]을 반환하는 메소드입니다.이제 ListReqDto에서 sortBy 필드에 맵핑하기 위한 setter 메소드를 작성합니다.
입력으로는 String을 받을 수 있지만 매칭되는 상수값이 없다면 IllegalArgumentException이 발생합니다.
public void setSortBy(String sortBy) { this.sortBy = SortBy.match(sortBy); }
OrderBy도 동일하게 변경해줍니다.
public enum OrderBy { DESC("desc"), ASC("asc"); private final String order; OrderBy(String order) { this.order = order.toLowerCase(); } public String getOrder() { return this.order; } public static OrderBy match(String order) { return Arrays.stream(OrderBy.values()) .filter((orderBy) -> orderBy.getOrder().equalsIgnoreCase(order)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("오름차순 혹은 내림차순을 선택해주세요. 입력: " + order)); } }
최종적으로 사용한 DTO의 모습입니다.
public class ListReqDto { @Schema(description = "페이지 (1부터 시작)", example = "1") @Min(value = 1, message = "page는 최소 1 이상이어야 합니다.") private int page = 1; @Schema(description = "페이지 사이즈", example = "10") @Min(value = 1, message = "size 최소 1 이상이어야 합니다.") private int size = 10; @Schema(description = "정렬 기준, 기본은 최신순 정렬입니다.", example = "recent", allowableValues = {"popular", "recent"}) private SortBy sortBy = SortBy.RECENT; @Schema(description = "오름차순/내림차순, 기본은 내림차순 정렬이빈다.", example = "desc", allowableValues = {"popular", "recent"}) private OrderBy orderBy = OrderBy.DESC; public void setSortBy(String sortBy) { this.sortBy = SortBy.match(sortBy); } public void setOrderBy(String orderBy) { this.orderBy = OrderBy.match(orderBy); } // NOTE: 프론트에서는 page가 1부터 시작하고 있어서 서버에서 -1을 합니다. public Pageable toPageable () { int page = this.page - 1; int size = this.size; Sort sort = orderBy.getOrder().equalsIgnoreCase(OrderBy.DESC.getOrder()) ? Sort.by(sortBy.getFieldName()).descending() : Sort.by(sortBy.getFieldName()).ascending(); return PageRequest.of(page, size, sort); } }
'운영 중인 서비스 > Coconut.' 카테고리의 다른 글
CloudWatch를 사용해서 Discord에서 EC2 상태 알림 받기 (0) 2024.02.16 내 서버는 얼마나 버틸 수 있는가 (0) 2024.02.15 조회수 변경 시 발생하는 레이스 컨디션과 해결 방법 (1) 2024.02.02 테스트를 쓰면서 만난 좋지 않은 Util 클래스와 의존성관리 (0) 2024.01.25 NumberFormatException (0) 2024.01.23