ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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);
      }
    }

     

Designed by Tistory.