Spring Boot/A-ger프로젝트 탄생의비화

spring-boot 프론트엔드와 무한 스크롤 구현 하기[ep.1]

뇌장하드 2022. 1. 17. 11:22

 

 

왼쪽은 페이징 표시 오른쪽은 무한 스크롤 기능입니다.

페이징 표시는 웹에서 사용하기 적합하지만 현재 만들고 있는 서비스는 모바일 웹에 특화된 서비스 이므로 무한 스크롤 기능을 적용을 해야합니다. 추후에는 앱으로도 만들어야겠다.

 

페이징 기능은 JPA에 Page로 반환을 해주면 간편하게 구현을 할수 있습니다.

Pageable로 값을 넣어주면 Db에서 데이터를 처음부터 끝까지 카운팅을 해준다음 pageable에 들어있는 size와 page를 보고 알아서 page에 대한 내용을 처리해줍니다.

여기서 size는 페이지에 보여줄 데이터 갯수입니다. 만약에 size: 3, page: 0 이라고 하면 0번째 페이지에 3개의 데이터를 불러와라 라고 볼수 있습니다.

이런식의 페이지 처리는 만약에 그냥 findAll이라면 Db에 저장된 데이터 갯수가 10000개 라면 findAll할때마다 만개의 데이터를 가져와야하는 과정은 성능에 대한 낭비이므로 페이지처리를 사용자가 보고 싶은 만큼만 데이터를 가져오게 하므로 사용자가 많은 서비스에서 성능을 최적화하는 작업이라고 생각합니다. 

 

  @GetMapping("/api/product")
    public ResponseEntity<ListResult<ProductResponse>> getlistAllProducts(
            @RequestPart(value = "page") Integer page,
            @RequestPart(value = "size") Integer size) {
        /**
         * @Method : getlistAllProducts
         * @Description :  페이지{page} 정보와 화면에 보이고 싶은 갯수{size}를 넘겨주면 그에 맞는 페이지를 불러온다.
         */
        return new ResponseEntity<>(responseService.getListResult(
                productService.findProductAllByCreatedAtDesc(page,size)), HttpStatus.OK);
    }

 

    public List<ProductResponse> findProductAllByCreatedAtDesc(Integer page, Integer size) {
        PageRequest pageRequest = PageRequest.of(page, size, Sort.by("createdAt").descending());
        return ProductResponse.toProductListResponse(productRepository.findAll(pageRequest).getContent());
    }

 

실제 구현하고 있는 서비스에서 적용을 한 부분입니다.

프론트에서 page와 size가 들어온다면 findProductAllByCreatedAtDesc함수에서 createAt을 기준으로 역순으로 정렬을 해준 pageRequest를 만들어서 productRepository에 이미 구현이된findAll에 넣어줍니다. 그다음 getContent()를 사용하여 컨텐츠를 꺼내와서 응답 엔티티에 넣어준후에 프론트로 보내주는 로직입니다.

 

 

 postman에서 적용해본 결과

 

Example Request

curl --location --request GET 'http://localhost:8080/api/product' \
--form 'page="0";type=application/json' \
--form 'size="3";type=application/json'

 

Example Response
{
  "success": true,
  "code": 0,
  "msg": "성공하였습니다.",
  "data": [
    {
      "productId": 11,
      "productName": "맥북프 삽니다 ",
      "productPrice": "100000000",
      "productDetail": "g304 새 상품",
      "productViewCnt": 0,
      "category": "삽니다",
      "status": "SALE",
      "createdAt": "2022-01-15T20:01:44.302669",
      "updatedAt": "2022-01-15T20:01:44.302669",
      "urlList": [
        "https://ager-s3.s3.ap-northeast-2.amazonaws.com/4d652614a42343f79aa72b02b6caf3b0.png"
      ]
    },
    {
      "productId": 10,
      "productName": "맥북프 삽니",
      "productPrice": "100000000",
      "productDetail": "g304 새 상품",
      "productViewCnt": 0,
      "category": "삽니다",
      "status": "SALE",
      "createdAt": "2022-01-15T20:01:37.806679",
      "updatedAt": "2022-01-15T20:01:37.806679",
      "urlList": [
        "https://ager-s3.s3.ap-northeast-2.amazonaws.com/a0782b632b0a4348b3a50becdb2690ce.png"
      ]
    },
    {
      "productId": 9,
      "productName": "맥북에어 팔아요 싸 ",
      "productPrice": "100000000",
      "productDetail": "g304 새 상품",
      "productViewCnt": 0,
      "category": "삽니다",
      "status": "SALE",
      "createdAt": "2022-01-15T20:01:18.083487",
      "updatedAt": "2022-01-15T20:01:18.083487",
      "urlList": [
        "https://ager-s3.s3.ap-northeast-2.amazonaws.com/ef040d7a970c4fccbfa465db183caffb.png"
      ]
    }
  ]
}