포인트 적립내역 조회 기능 개발 및 최적화

금은체리·2024년 6월 12일
0

1. 기능 설명

포인트 사용내역 조회 기능을 통해 사용자는 본인의 포인트 적립 타입, 적립액, 생성 시간을 확인할 수 있습니다. 이를 무한스크롤 페이지네이션 방식으로 구현하여 응답 시간을 최적화하였습니다.

2. 문제 및 해결 과정

2.1 초기 구현 및 문제 발생

초기 문제:
초기 구현 시에는 포인트 적립내역 조회 기능을 페이지네이션 없이 구현하였습니다. 이로 인해 모든 데이터를 한 번에 가져오게 되어 응답 시간이 길어졌습니다. 아래는 초기 상태의 응답 시간입니다:

  • 총 응답 시간: 28.39ms

해결 과정:
응답 시간을 최적화하기 위해 무한스크롤 페이지네이션을 도입하기로 결정하였습니다. 이를 통해 사용자는 필요할 때만 데이터를 불러오게 되어 서버 부하를 줄이고 응답 시간을 단축할 수 있습니다.

2.2 무한스크롤 페이지네이션 도입

구현 단계:

  1. Repository 수정:
    SavedPointRepository에 무한스크롤 페이지네이션을 위한 메서드를 추가하였습니다.

    package team9502.sinchulgwinong.domain.point.repository;
    
    import team9502.sinchulgwinong.domain.point.entity.SavedPoint;
    
    import java.util.List;
    
    public interface SavedPointRepositoryCustom {
        List<SavedPoint> findSavedPointsWithCursor(Long pointId, Long cursorId, int limit);
    }
  2. Service 수정:
    페이지네이션 로직을 서비스 계층에 추가하였습니다.

    @Transactional(readOnly = true)
    public List<SavedPointDetailResponseDTO> getSpDetails(UserDetailsImpl userDetails, Long cursorId, int limit) {
        Long pointId = getPointIdFromUser(userDetails);
        cursorId = (cursorId == null) ? Long.MAX_VALUE : cursorId;
        List<SavedPoint> savedPoints = savedPointRepository.findSavedPointsWithCursor(pointId, cursorId, limit);
        return convertToSavedPointDetailResponseDTO(savedPoints);
    }
  3. Controller 수정:
    @RequestParam을 통해 클라이언트가 커서와 제한 값을 전달할 수 있도록 하였습니다.

    @GetMapping("/details")
    @Operation(summary = "포인트 적립 내역 조회", description = "로그인한 사용자의 포인트 적립 내역을 커서 기반 페이지네이션으로 조회합니다.")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "포인트 적립 내역 조회 성공", content = @Content(mediaType = "application/json", examples = @ExampleObject(value = "{ \"code\": \"200\", \"message\": \"적립 포인트 조회 성공\", \"data\": [{\"type\": \"REVIEW\", \"savedPoint\": 300, \"createdAt\": \"2024-06-11\"}, {\"type\": \"SIGNUP\", \"savedPoint\": 300, \"createdAt\": \"2024-06-11\"}] }"))),
        @ApiResponse(responseCode = "404", description = "포인트를 찾을 수 없습니다.", content = @Content(mediaType = "application/json", examples = @ExampleObject(value = "{ \"code\": \"404\", \"message\": \"포인트를 찾을 수 없습니다.\", \"data\": null }"))),
        @ApiResponse(responseCode = "500", description = "서버 에러", content = @Content(mediaType = "application/json", examples = @ExampleObject(value = "{ \"code\": \"500\", \"message\": \"서버 에러\", \"data\": null }")))
    })
    public ResponseEntity<GlobalApiResponse<List<SavedPointDetailResponseDTO>>> getPointDetails(
            @AuthenticationPrincipal UserDetailsImpl userDetails,
            @RequestParam(value = "cursorId", required = false) Long cursorId,
            @RequestParam(value = "limit", defaultValue = "6") int limit) {
    
        List<SavedPointDetailResponseDTO> responseDTOs = pointService.getSpDetails(userDetails, cursorId, limit);
        return ResponseEntity.status(SUCCESS_SAVED_POINT_READ.getHttpStatus())
                .body(GlobalApiResponse.of(SUCCESS_SAVED_POINT_READ.getMessage(), responseDTOs));
    }
2.3 결과 확인 및 최적화

결과 확인:
페이지네이션 도입 후 응답 시간이 크게 줄어드는 것을 확인할 수 있었습니다.

  • 페이지네이션 도입 후 총 응답 시간: 14.95ms
2.4 스웨거 문서화

개발자 정보 추가:
스웨거 문서화 시, 백엔드 개발자 정보도 함께 추가하여 사용자들이 쉽게 연락할 수 있도록 하였습니다.

package team9502.sinchulgwinong.global.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.OpenAPI;

@Configuration
public class SwaggerConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("신출귀농 API 문서")
                        .description("신출귀농 애플리케이션의 API 문서입니다.\n\n백엔드 개발자:\n\n김은채 - ke808762@gmail.com\n\n창다은 - cdaeun95@gmail.com")
                        .version("1.0.0")
                        .contact(new Contact().name("9502").email("9502team@gmail.com")));
    }
}

3. 선택지 및 선택 이유

  • 전체 데이터 조회:
    모든 데이터를 한 번에 가져오는 방법은 간단하지만, 데이터가 많아지면 응답 시간이 길어지고 서버 부하가 커집니다. 이는 사용자 경험에 악영향을 미칠 수 있습니다.
  • 페이지네이션 도입:
    페이지네이션을 도입하면 필요한 데이터만 가져와 응답 시간을 줄이고 서버 부하를 줄일 수 있습니다. 특히 무한스크롤 페이지네이션은 사용자가 스크롤할 때마다 추가 데이터를 로드할 수 있어 사용자 경험을 향상시킵니다. 이 방법을 선택한 이유는 성능 최적화와 사용자 경험을 동시에 개선할 수 있기 때문입니다.

4. 결론

페이지네이션을 통한 최적화를 통해 응답 시간을 28.39ms에서 14.95ms으로 약 47% 개선되었고, 사용자 경험을 향상시켰습니다. 스웨거 문서화 작업을 통해 API 사용자들과 팀원들에게 더 나은 접근성을 제공하였습니다. 이번 경험을 통해 성능 최적화의 중요성을 다시 한번 인식하게 되었으며, 앞으로도 이러한 접근 방식을 유지해 나가고자합니다.

profile
전 체리 알러지가 있어요!

0개의 댓글