Skip to content
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

[BE] refactor: 세션을 가져오는 역할을 ReviewGroupSessionResolver에 위임 #843

Merged
merged 9 commits into from
Oct 15, 2024
9 changes: 7 additions & 2 deletions backend/src/main/java/reviewme/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package reviewme.config;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import reviewme.global.HeaderPropertyArgumentResolver;
import reviewme.reviewgroup.controller.ReviewGroupSessionResolver;
import reviewme.reviewgroup.service.ReviewGroupService;

@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {

private final ReviewGroupService reviewGroupService;

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new HeaderPropertyArgumentResolver());
resolvers.add(new ReviewGroupSessionResolver(reviewGroupService));
}
}
18 changes: 0 additions & 18 deletions backend/src/main/java/reviewme/global/HeaderProperty.java

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;
import reviewme.highlight.service.HighlightService;
import reviewme.highlight.service.dto.HighlightsRequest;
import reviewme.reviewgroup.controller.ReviewGroupSession;
import reviewme.reviewgroup.domain.ReviewGroup;

@RestController
@RequiredArgsConstructor
Expand All @@ -19,9 +20,9 @@ public class HighlightController {
@PostMapping("/v2/highlight")
public ResponseEntity<Void> highlight(
@Valid @RequestBody HighlightsRequest request,
@SessionAttribute("reviewRequestCode") String reviewRequestCode
@ReviewGroupSession ReviewGroup reviewGroup
) {
highlightService.highlight(request, reviewRequestCode);
highlightService.highlight(request, reviewGroup);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,20 @@
import reviewme.highlight.service.validator.HighlightValidator;
import reviewme.review.domain.Answer;
import reviewme.review.repository.AnswerRepository;
import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException;
import reviewme.reviewgroup.repository.ReviewGroupRepository;
import reviewme.reviewgroup.domain.ReviewGroup;

@Service
@RequiredArgsConstructor
public class HighlightService {

private final HighlightRepository highlightRepository;
private final ReviewGroupRepository reviewGroupRepository;
private final AnswerRepository answerRepository;

private final HighlightValidator highlightValidator;

@Transactional
public void highlight(HighlightsRequest request, String reviewRequestCode) {
long reviewGroupId = reviewGroupRepository.findByReviewRequestCode(reviewRequestCode)
.orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(reviewRequestCode))
.getId();

public void highlight(HighlightsRequest request, ReviewGroup reviewGroup) {
long reviewGroupId = reviewGroup.getId();
highlightValidator.validate(request, reviewGroupId);
deleteOldHighlight(request.questionId(), reviewGroupId);
saveNewHighlight(request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;
import reviewme.review.service.ReviewGatheredLookupService;
import reviewme.review.service.ReviewDetailLookupService;
import reviewme.review.service.ReviewGatheredLookupService;
import reviewme.review.service.ReviewListLookupService;
import reviewme.review.service.ReviewRegisterService;
import reviewme.review.service.ReviewSummaryService;
import reviewme.review.service.dto.request.ReviewRegisterRequest;
import reviewme.review.service.dto.response.detail.ReviewDetailResponse;
import reviewme.review.service.dto.response.gathered.ReviewsGatheredBySectionResponse;
import reviewme.review.service.dto.response.list.ReceivedReviewsSummaryResponse;
import reviewme.review.service.dto.response.list.ReceivedReviewsResponse;
import reviewme.review.service.dto.response.list.ReceivedReviewsSummaryResponse;
import reviewme.reviewgroup.controller.ReviewGroupSession;
import reviewme.reviewgroup.domain.ReviewGroup;

@RestController
@RequiredArgsConstructor
Expand All @@ -42,37 +43,36 @@ public ResponseEntity<Void> createReview(@Valid @RequestBody ReviewRegisterReque
public ResponseEntity<ReceivedReviewsResponse> findReceivedReviews(
@RequestParam(required = false) Long lastReviewId,
@RequestParam(required = false) Integer size,
@SessionAttribute("reviewRequestCode") String reviewRequestCode
@ReviewGroupSession ReviewGroup reviewGroup
) {
ReceivedReviewsResponse response = reviewListLookupService.getReceivedReviews(
lastReviewId, size, reviewRequestCode);
ReceivedReviewsResponse response = reviewListLookupService.getReceivedReviews(lastReviewId, size, reviewGroup);
return ResponseEntity.ok(response);
}

@GetMapping("/v2/reviews/{id}")
public ResponseEntity<ReviewDetailResponse> findReceivedReviewDetail(
@PathVariable long id,
@SessionAttribute("reviewRequestCode") String reviewRequestCode
@ReviewGroupSession ReviewGroup reviewGroup
) {
ReviewDetailResponse response = reviewDetailLookupService.getReviewDetail(id, reviewRequestCode);
ReviewDetailResponse response = reviewDetailLookupService.getReviewDetail(id, reviewGroup);
return ResponseEntity.ok(response);
}

@GetMapping("/v2/reviews/summary")
public ResponseEntity<ReceivedReviewsSummaryResponse> findReceivedReviewOverview(
@SessionAttribute("reviewRequestCode") String reviewRequestCode
@ReviewGroupSession ReviewGroup reviewGroup
) {
ReceivedReviewsSummaryResponse response = reviewSummaryService.getReviewSummary(reviewRequestCode);
ReceivedReviewsSummaryResponse response = reviewSummaryService.getReviewSummary(reviewGroup);
return ResponseEntity.ok(response);
}

@GetMapping("/v2/reviews/gather")
public ResponseEntity<ReviewsGatheredBySectionResponse> getReceivedReviewsBySectionId(
@RequestParam("sectionId") long sectionId,
@SessionAttribute("reviewRequestCode") String reviewRequestCode
@ReviewGroupSession ReviewGroup reviewGroup
) {
ReviewsGatheredBySectionResponse response = reviewGatheredLookupService.getReceivedReviewsBySectionId(
reviewRequestCode, sectionId);
ReviewsGatheredBySectionResponse response =
reviewGatheredLookupService.getReceivedReviewsBySectionId(reviewGroup, sectionId);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,20 @@
import reviewme.review.domain.Review;
import reviewme.review.repository.ReviewRepository;
import reviewme.review.service.dto.response.detail.ReviewDetailResponse;
import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException;
import reviewme.review.service.exception.ReviewNotFoundByIdAndGroupException;
import reviewme.review.service.mapper.ReviewDetailMapper;
import reviewme.reviewgroup.domain.ReviewGroup;
import reviewme.reviewgroup.repository.ReviewGroupRepository;

@Service
@Transactional(readOnly = true)
@AllArgsConstructor
public class ReviewDetailLookupService {

private final ReviewRepository reviewRepository;
private final ReviewGroupRepository reviewGroupRepository;

private final ReviewDetailMapper reviewDetailMapper;

@Transactional(readOnly = true)
public ReviewDetailResponse getReviewDetail(long reviewId, String reviewRequestCode) {
ReviewGroup reviewGroup = reviewGroupRepository.findByReviewRequestCode(reviewRequestCode)
.orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(reviewRequestCode));

public ReviewDetailResponse getReviewDetail(long reviewId, ReviewGroup reviewGroup) {
Review review = reviewRepository.findByIdAndReviewGroupId(reviewId, reviewGroup.getId())
.orElseThrow(() -> new ReviewNotFoundByIdAndGroupException(reviewId, reviewGroup.getId()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
import reviewme.review.domain.Answer;
import reviewme.review.repository.AnswerRepository;
import reviewme.review.service.dto.response.gathered.ReviewsGatheredBySectionResponse;
import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException;
import reviewme.review.service.exception.SectionNotFoundInTemplateException;
import reviewme.review.service.mapper.ReviewGatherMapper;
import reviewme.reviewgroup.domain.ReviewGroup;
import reviewme.reviewgroup.repository.ReviewGroupRepository;
import reviewme.template.domain.Section;
import reviewme.template.repository.SectionRepository;

Expand All @@ -28,25 +26,18 @@ public class ReviewGatheredLookupService {

private final QuestionRepository questionRepository;
private final AnswerRepository answerRepository;
private final ReviewGroupRepository reviewGroupRepository;
private final SectionRepository sectionRepository;

private final ReviewGatherMapper reviewGatherMapper;

@Transactional(readOnly = true)
public ReviewsGatheredBySectionResponse getReceivedReviewsBySectionId(String reviewRequestCode, long sectionId) {
ReviewGroup reviewGroup = getReviewGroupOrThrow(reviewRequestCode);
public ReviewsGatheredBySectionResponse getReceivedReviewsBySectionId(ReviewGroup reviewGroup, long sectionId) {
Section section = getSectionOrThrow(sectionId, reviewGroup);
Map<Question, List<Answer>> questionAnswers = getQuestionAnswers(section, reviewGroup);

return reviewGatherMapper.mapToReviewsGatheredBySection(questionAnswers);
}

private ReviewGroup getReviewGroupOrThrow(String reviewRequestCode) {
return reviewGroupRepository.findByReviewRequestCode(reviewRequestCode)
.orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(reviewRequestCode));
}

private Section getSectionOrThrow(long sectionId, ReviewGroup reviewGroup) {
return sectionRepository.findByIdAndTemplateId(sectionId, reviewGroup.getTemplateId())
.orElseThrow(() -> new SectionNotFoundInTemplateException(sectionId, reviewGroup.getTemplateId()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,18 @@
import reviewme.review.repository.ReviewRepository;
import reviewme.review.service.dto.response.list.ReceivedReviewsResponse;
import reviewme.review.service.dto.response.list.ReviewListElementResponse;
import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException;
import reviewme.review.service.mapper.ReviewListMapper;
import reviewme.reviewgroup.domain.ReviewGroup;
import reviewme.reviewgroup.repository.ReviewGroupRepository;

@Service
@RequiredArgsConstructor
public class ReviewListLookupService {

private final ReviewGroupRepository reviewGroupRepository;
private final ReviewRepository reviewRepository;
private final ReviewListMapper reviewListMapper;

@Transactional(readOnly = true)
public ReceivedReviewsResponse getReceivedReviews(Long lastReviewId, Integer size, String reviewRequestCode) {
ReviewGroup reviewGroup = reviewGroupRepository.findByReviewRequestCode(reviewRequestCode)
.orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(reviewRequestCode));

public ReceivedReviewsResponse getReceivedReviews(Long lastReviewId, Integer size, ReviewGroup reviewGroup) {
PageSize pageSize = new PageSize(size);
List<ReviewListElementResponse> reviewListResponse
= reviewListMapper.mapToReviewList(reviewGroup, lastReviewId, pageSize.getSize());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,16 @@
import org.springframework.transaction.annotation.Transactional;
import reviewme.review.repository.ReviewRepository;
import reviewme.review.service.dto.response.list.ReceivedReviewsSummaryResponse;
import reviewme.review.service.exception.ReviewGroupNotFoundByReviewRequestCodeException;
import reviewme.reviewgroup.domain.ReviewGroup;
import reviewme.reviewgroup.repository.ReviewGroupRepository;

@Service
@RequiredArgsConstructor
public class ReviewSummaryService {

private final ReviewGroupRepository reviewGroupRepository;
private final ReviewRepository reviewRepository;

@Transactional(readOnly = true)
public ReceivedReviewsSummaryResponse getReviewSummary(String reviewRequestCode) {
ReviewGroup reviewGroup = reviewGroupRepository.findByReviewRequestCode(reviewRequestCode)
.orElseThrow(() -> new ReviewGroupNotFoundByReviewRequestCodeException(reviewRequestCode));

public ReceivedReviewsSummaryResponse getReviewSummary(ReviewGroup reviewGroup) {
int totalReviewCount = reviewRepository.countByReviewGroupId(reviewGroup.getId());

return new ReceivedReviewsSummaryResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package reviewme.reviewgroup.controller;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ReviewGroupSession {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package reviewme.reviewgroup.controller;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.BadRequestException;

@Slf4j
public class ReviewGroupSessionNotFoundException extends BadRequestException {

public ReviewGroupSessionNotFoundException() {
super("리뷰 그룹 세션이 존재하지 않아요.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package reviewme.reviewgroup.controller;
Copy link
Contributor

@skylar1220 skylar1220 Oct 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

의견)
패키지 위치는 지금처럼 reviewGroup.controller가 적절하다고 생각해요.

  • 요청이 컨트롤러로 들어오고 → 해당하는 부분 처리를 리졸버로 보냈다가 → 컨트롤러로 다시 받아서 다음 처리를 한다.

위처럼 컨트롤러의 처리 사이에서만 쓰이기때문이죠!


import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import reviewme.reviewgroup.domain.ReviewGroup;
import reviewme.reviewgroup.service.ReviewGroupService;

@RequiredArgsConstructor
public class ReviewGroupSessionResolver implements HandlerMethodArgumentResolver {

private static final String SESSION_KEY = "reviewRequestCode";

private final ReviewGroupService reviewGroupService;

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(ReviewGroupSession.class);
}

@Override
public ReviewGroup resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
HttpSession session = request.getSession(false);

// 세션이 없거나, 세션 안에 reviewRequestCode가 존재하지 않는 경우
if (session == null) {
throw new ReviewGroupSessionNotFoundException();
}
String reviewRequestCode = (String) session.getAttribute(SESSION_KEY);
if (reviewRequestCode == null) {
throw new ReviewGroupSessionNotFoundException();
}
return reviewGroupService.getReviewGroupByReviewRequestCode(reviewRequestCode);
}
}
Loading