포인트 사용내역 조회 기능을 통해 사용자는 본인의 포인트 적립 타입, 적립액, 생성 시간을 확인할 수 있습니다. 이를 무한스크롤 페이지네이션 방식으로 구현하여 응답 시간을 최적화하였습니다.
초기 문제:
초기 구현 시에는 포인트 적립내역 조회 기능을 페이지네이션 없이 구현하였습니다. 이로 인해 모든 데이터를 한 번에 가져오게 되어 응답 시간이 길어졌습니다. 아래는 초기 상태의 응답 시간입니다:
해결 과정:
응답 시간을 최적화하기 위해 무한스크롤 페이지네이션을 도입하기로 결정하였습니다. 이를 통해 사용자는 필요할 때만 데이터를 불러오게 되어 서버 부하를 줄이고 응답 시간을 단축할 수 있습니다.
구현 단계:
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);
}
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);
}
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));
}
결과 확인:
페이지네이션 도입 후 응답 시간이 크게 줄어드는 것을 확인할 수 있었습니다.
개발자 정보 추가:
스웨거 문서화 시, 백엔드 개발자 정보도 함께 추가하여 사용자들이 쉽게 연락할 수 있도록 하였습니다.
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")));
}
}
페이지네이션을 통한 최적화를 통해 응답 시간을 28.39ms에서 14.95ms으로 약 47% 개선되었고, 사용자 경험을 향상시켰습니다. 스웨거 문서화 작업을 통해 API 사용자들과 팀원들에게 더 나은 접근성을 제공하였습니다. 이번 경험을 통해 성능 최적화의 중요성을 다시 한번 인식하게 되었으며, 앞으로도 이러한 접근 방식을 유지해 나가고자합니다.