티스토리 뷰

반응형

Page 인터페이스

Paging을 위해서 Spring boot에서는 Page 인터페이스를 제공합니다. 이 인터페이스의 기본 스펙을 살펴보면 다음과 같습니다.

{
  "content": [
      ... (data)
  ],
  "pageable": {
    "sort": {
      "unsorted": false,
      "sorted": true,
      "empty": false
    },
    "pageNumber": 0,
    "pageSize": 7,
    "offset": 0,
    "paged": true,
    "unpaged": false
  },
  "last": true,
  "totalElements": 7,
  "totalPages": 1,
  "first": true,
  "numberOfElements": 7,
  "size": 7,
  "sort": {
    "unsorted": false,
    "sorted": true,
    "empty": false
  },
  "number": 0,
  "empty": false
}

Page 인터페이스를 통해 리턴을 해주면 FE는 pageable 정보를 기반으로 화면에 적절한 UI를 보여줍니다. 이 인터페이스는 Spring에서 제공해주는 interface로 페이징한 데이터를 간편하게 반환해줄 수 있습니다.

Page 인터페이스의 단점

1. 비용 문제

page 인터페이스는 기본적으로 Spring에서 제공해주는 interface기 때문에 공통화를 위해 내부에 굉장히 많은 데이터가 필요합니다. 다만 이 데이터들이 굉장히 많이 들어있는데 이 인터페이스에는 너무 많은 데이터들이 들어있습니다.

최근 트랜드는 클라우드에서의 비용을 줄이기 위해 네트워크 통신 시 비용을 최소화하고 있습니다. 실제로 AWS 문서를 참고하면 다음과 같은 내용이 들어있습니다.

애플리케이션 및 쿼리 디자인을 검토합니다. 애플리케이션과 데이터 저장소 간에 전송되는 데이터의 양을 줄이는 방법을 찾으십시오. 읽기 전용 복제본을 사용하도록 애플리케이션 또는 쿼리를 설계하는 것이 좋습니다.

https://aws.amazon.com/ko/blogs/korea/exploring-data-transfer-costs-for-aws-managed-databases/

 

AWS 관리형 데이터베이스 서비스 전송 비용 알아보기 | Amazon Web Services

여러분은 애플리케이션의 목적에 따라  관계형, 키-값, 문서, 인메모리, 그래프, 시계열, 칼럼 또는 원장 등 AWS 관리형 데이터베이스 서비스를 선택할 수 있습니다. 이때, DB 서비스 내 데이터 전

aws.amazon.com

 

 

또한 네트워크는 세그먼트 단위로 전송 되기 때문에 데이터가 많다면 FE서버와 BE 서버간에 커넥션 시간도 길어진다고 고려가 되는 상황입니다.

이런 면에서 Page 인터페이스의 모든 데이터를 FE서버에서 이용하는 것이 아니라면 불필요한 데이터 때문에 계속해서 서버간 커넥션과 네트워크 통신 비용이 낭비되는 상황입니다.

2. 인터페이스 자체 유연성 낮음

Page 인터페이스는 공통으로 사용하기 위해 만들어진 Spring 제공 인터페이스로 외부에서 수정이 불가합니다. 하지만 외부에서 데이터를 전송해줄 때 항상 여러가지 상황을 고려해야하여 Page는 적합하지 않다고 생각했습니다.

코드를 예시로 들어보겠습니다.

 
ResponseEntity<Page<MemberResponse>> getMembers(final Pageable pageable) {
  // ... //
}​

다음과 같은 회원 정보들의 정보를 리턴해주는 api가 존재한다고 생각했을 때 당장은 문제가 없어 보입니다.

 

하지만 만약 저 api에서 호출한 사용자 정보를 리턴하는 요구사항이 들어왔다고 가정해봅니다. 우리는 Page 인터페이스 내부를 수정할 수 없기 때문에 하나의 DTO를 만들 수 밖에 없습니다. 그렇다면 굉장히 많은 변화가 필요한 상황입니다.
실제로 테스트 코드를 의무화하고 있다면 testcode에도 굉장히 많은 변화가 필요합니다.

Page 인터페이스 커스텀하기

위와 같은 문제를 해결하고 Page 인터페이스의 장점만을 최대한 살리기 위해 Page<> 인터페이스를 매게 변수로 만든 custom 객체를 이용할 수 있습니다. 구조는 다음과 같습니다.

 

public class PageCustomResponse<T> {
    private List<T> data = new ArrayList<>();
    private long totalPage;
    private int pageSize;
    private long totalElements;
    private int number;

    public static <T> PageCustomResponse<T> of(Page<T> response) {
        return new PageCustomResponse<>(
                response.getContent(),
                response.getTotalPages(),
                response.getSize(),
                response.getTotalElements(),
                response.getNumber());
    }
}

 

위와 같이 커스텀을 하였을 때 다음과 같은 장점을 얻을 수 있습니다.

  1. 네트워크 비용을 최소화하여 클라우드 비용 자체를 줄일 수 있다.
  2. 넘겨줘야할 데이터가 적기 때문에 커넥션 유지 자체가 길어지지 않는다.
  3. 사용자가 정의한 객체기 때문에 요구사항이 변경되더라도 코드 한줄 간단하게 추가하여 해결할 수 있다.
  4. 일부 요구사항만 변경된다 하더라도 공통적으로 쓰이는 Page객체로 되어 있기 때문에 해당 객체를 복사하여 코드 한줄과 이름만 변경해주면 쉽게 변경할 수 있다.

 

물론 장점만이 있는 것은 아닙니다. Custom을 하게 된다면 WAS내에선 객체가 하나 더 생겨버려 Heap 메모리나 GC동작에 있어 stop the world가 비교적 많이 발생하기에 적용하기 전에 고려해야할 상황은 반드시 있습니다.

 

마침.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함