-
Notifications
You must be signed in to change notification settings - Fork 1
[refactor] 좋아요 API 성능 최적화 및 유저 식별 방식 변경 #194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough좋아요 API의 userId 파라미터 처리 방식을 리팩터링했습니다. 컨트롤러에서 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@CodeRabbit review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/repository/SpringDataPostLikeRepository.java (1)
30-32: LGTM! @Modifying 쿼리의 반환 타입 변경이 올바릅니다.JPQL DELETE 쿼리에서
int반환 타입을 사용하여 영향받은 행 수를 정확히 받아올 수 있습니다.선택적 최적화: @Modifying 옵션 고려
동일 트랜잭션 내에서 삭제 전 다른 변경 작업이 있을 경우,
flushAutomatically = true옵션을 추가하면 더 안전합니다:-@Modifying +@Modifying(flushAutomatically = true) @Query("DELETE FROM PostLikeEntity pl WHERE pl.user.userId = :userId AND pl.post.postId = :postId") int deleteByUserIdAndPostIdQuery(@Param("userId") Long userId, @Param("postId") Long postId);현재는 단순 삭제 연산이므로 기본값으로도 충분하지만, 향후 복잡한 트랜잭션 시나리오에서 예기치 않은 동작을 방지할 수 있습니다.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostLikeController.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/application/service/PostLikeService.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/domain/repository/PostLikeRepository.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/repository/PostLikeRepositoryImpl.javasrc/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/repository/SpringDataPostLikeRepository.java
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: daeun-han
Repo: PAW-KEY/PAWKEY-Backend PR: 55
File: src/main/java/org/sopt/pawkey/backendapi/domain/user/application/facade/query/UserLikedPostQueryFacade.java:55-55
Timestamp: 2025-07-13T11:54:29.024Z
Learning: 좋아요한 게시물 목록을 조회하는 API에서 isLiked 필드를 true로 하드코딩하는 것은 성능상 합리적입니다. PostLikeEntity 리스트가 이미 좋아요를 누른 게시물들만 포함하므로 별도 쿼리로 좋아요 상태를 확인하는 것은 중복이고 비효율적입니다.
🔇 Additional comments (5)
src/main/java/org/sopt/pawkey/backendapi/domain/Post/domain/repository/PostLikeRepository.java (1)
15-15: LGTM! 성능 최적화를 위한 반환 타입 변경이 적절합니다.삭제된 행 수를 반환하도록 변경하여 호출부에서 exists 체크 없이 바로 삭제 결과를 확인할 수 있게 되었습니다. 이를 통해 쿼리 실행 횟수를 절반으로 줄일 수 있습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/Post/infra/persistence/repository/PostLikeRepositoryImpl.java (1)
30-31: LGTM! 인터페이스 시그니처에 맞춰 올바르게 구현되었습니다.JPA Repository의 반환값을 그대로 전달하여 삭제된 행 수를 상위 레이어에서 활용할 수 있도록 했습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/Post/api/controller/PostLikeController.java (2)
36-41: LGTM! 보안성이 크게 개선되었습니다.JWT 기반 인증으로 userId를 추출하고
@Parameter(hidden = true)를 사용하여 Swagger 문서에서 숨기는 방식은:
- 클라이언트가 임의로 userId를 조작하는 것을 방지합니다.
- API 문서가 실제 사용 방식과 정확히 일치합니다.
- 인증된 사용자만 자신의 좋아요를 저장할 수 있도록 보장합니다.
53-59: LGTM! like 메서드와 일관되게 보안이 개선되었습니다.좋아요 취소 API도 동일한 방식으로 JWT 기반 인증을 사용하여 사용자 식별의 일관성과 보안성을 확보했습니다.
src/main/java/org/sopt/pawkey/backendapi/domain/Post/application/service/PostLikeService.java (1)
35-39: 훌륭한 성능 최적화입니다! 동시성 안전성도 함께 개선되었습니다.exists + delete 패턴을 제거하고 delete 결과값으로 판단하는 방식으로 변경하여:
- 쿼리 실행 횟수를 절반으로 감소시켰습니다.
- TOCTOU(time-of-check to time-of-use) 문제를 해결하여 동시성 안전성이 향상되었습니다.
트랜잭션 관리도 문제없습니다. PostLikeFacade에서
@Transactional어노테이션으로 트랜잭션 경계가 관리되고 있으며, Spring의 기본 전파 방식(PROPAGATION_REQUIRED)에 의해 PostLikeService의cancelLike()메서드는 Facade의 트랜잭션 컨텍스트 내에서 실행됩니다. 따라서@Modifying쿼리도 정상적으로 동작합니다.
📌 PR 제목
ex) [refactor] 좋아요 API 성능 최적화 및 유저 식별 방식 변경
✨ 요약 설명
좋아요 저장 및 취소 API의 유저 식별 방식을 인증 헤더 기반으로 변경하고, 쿼리 실행 횟수를 최적화하여 서버 부하를 줄였습니다.
🧾 변경 사항
📂 PR 타입
🧪 테스트
✅ 체크리스트
💬 리뷰어에게 전달할 말
좋아요 api 관련하여 인증 헤더로 유저를 식별하는 점을 적용하였습니다.
또한, 좋아요 취소 시 exists 쿼리 없이 곧바로 삭제를 시도하고, 결과값이 0인 경우 예외를 던지도록 설계하여 쿼리 횟수를 최적화했습니다. 이를 위해 SpringDataPostLikeRepository의 반환 타입을 void에서 int로 변경했습니다.
사실 현재 규모에서 쿼리 1회를 줄이는 것이 오버엔지니어링일까 우려됐지만, 빈번한 인터랙션이 발생하는 기능 특성상 성능과 동시성을 함께 고려해보고 싶어 이 방식을 채택해보았습니다. 팀의 컨벤션에 비해 과한 접근은 아닌지 의견 주시면 감사하겠습니다!
🔗 관련 이슈
Summary by CodeRabbit
릴리스 노트
✏️ Tip: You can customize this high-level summary in your review settings.