-
Notifications
You must be signed in to change notification settings - Fork 2
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] docs: 작성한 리뷰 목록 조회, 회원용 리뷰 그룹 생성, 리뷰 그룹 정보, 리뷰 등록 API 문서를 작성한다. #1017
base: develop
Are you sure you want to change the base?
Conversation
Test Results161 tests +4 158 ✅ +4 5s ⏱️ -1s Results for commit 13c10ed. ± Comparison against base commit 69b507a. This pull request removes 3 and adds 7 tests. Note that renamed tests count towards both.
♻️ This comment has been updated with latest results. |
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.
따라서 리뷰 그룹 응답에 단순히 리뷰 그룹의 주인 ID(필드명 : revieweeId)를 nullable로 제공하는 것으로 했습니다.
-> 회원이 생성한 리뷰 그룹인 경우, 회원ID가 함께 제공
-> 비회원이 생성한 리뷰 그룹인 경우, 회원ID는 null로 제공
바뀐 방법이 더 좋아보입니다👍
추후 필요한 것 : 프론트가 로그인 사용자의 정보를 따로 저장하지 않는다면, 로그인 세션을 통해 회원 정보(memberId)를 응답하는 API 구현
memberId 를 프로필 사진 / 닉네임을 담는 dto 에 포함하게 할까요?
==== 비회원이 리뷰 생성 | ||
|
||
operation::create-review[snippets="curl-request,request-fields,http-response"] | ||
operation::create-review-by-guest[snippets="curl-request,request-fields,http-response"] | ||
|
||
==== 회원이 리뷰 생성 | ||
|
||
operation::create-review-by-member[snippets="curl-request,request-fields,http-response"] |
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.
하나의 api 를 사용하되, 세션에 따라서 회원과 비회원을 구분한다는 선택지도 있었을 것 같아요.
그것을 선택하지 않고 이렇게 api 를 분리한 이유가 있나요?
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.
회원/비회원 리뷰 생성 API를 하나로 했을때를 생각해보았는데요.
@PostMapping("/v2/reviews")
public ResponseEntity<Void> createReview(
@Valid @RequestBody ReviewRegisterRequest request,
@MemberSession Member member
) {
long savedReviewId = reviewRegisterService.registerReview(request, member);
return ResponseEntity.created(URI.create("/reviews/" + savedReviewId)).build();
}
이때, 비회원일 경우 세션이 없지만, resolver에서 예외를 터뜨리거나 하지 않고 컨트롤러까지 다시 member 객체를 null로 반환하는 형식으로 처리를 해줘야합니다. 그리고 서비스에서 이를 확인해서 비회원용 로직으로 처리하게 되겠죠. 이렇게, 하나의 API에서 세션이 null인 것을 예외가 아닌 비회원임으로 인식하고 처리하기 위해서 예외를 터뜨려야하는데 다르게 처리하는 등으로 로직이 복잡해진다고 생각했어요.
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.
지난 회의에서 이야기 나온 것처럼, 하나의 api를 여러곳에서 쓰고, 권한에 맞게 별도의 로직을 제공하려는 우리의 취지를 생각해봤어요. 그럼 하나의 api에서 처리하는게 맞는 것 같아요.
그리고 저도 확실하지 않아서 지피티 & 클로드에게 물어보니, 회원/비회원 기능을 하나의 api에서 제공하고 내부적으로 분기하는 것은 일반적인 패턴이라고 합니다. 아래의 예시 코드처럼요.
@Service
public class ProductService {
public ProductResponse getProduct(Long id, User user) {
Product product = productRepository.findById(id);
ProductResponse response = new ProductResponse(product);
if (user != null) {
// 회원용 추가 정보 설정
response.setPersonalizedPrice(calculatePersonalPrice(product, user));
response.setUserSpecificData(getUserData(product, user));
} else {
// 비회원용 기본 정보만 설정
response.setDefaultPrice(product.getPrice());
}
return response;
}
}
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.
- 위의 코드로 구현할 수 있지만 앞에서 언급한 문제가 여전히 존재한다고 생각해요.
하나의 API에서 세션이 null인 것을 예외가 아닌 비회원임으로 인식하고 처리하기 위해서, resolver에서 예외를 터뜨려야하는데 다르게 처리하는 등으로 로직이 복잡해진다고 생각했어요.
- api 재사용 논의와 관련해서는, 구현하면서 아직 하나의 api를 재사용하고 세션 권한 체계로 구분한다는 것의 상세구현이 그려지지 않았어요. 그래서 일단 세션을 나눠서 적용했을 때 문제가 없게 두가지 api로 나눠 구현했습니다..!
backend/src/main/java/reviewme/review/service/ReviewListLookupService.java
Outdated
Show resolved
Hide resolved
backend/src/main/java/reviewme/review/service/dto/response/list/WrittenReviewsResponse.java
Show resolved
Hide resolved
backend/src/main/java/reviewme/reviewgroup/controller/ReviewGroupController.java
Show resolved
Hide resolved
// CookieDescriptor[] cookieDescriptors = { | ||
// cookieWithName("JSESSIONID").description("세션 ID") | ||
// }; |
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.
이 부분은 왜 주석처리 했나요? 자신이 작성한 것을 볼 때도 session 을 사용하지 않나요?
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.
자신이 작성한 것을 볼때는 기존의 리뷰그룹세션이 아닌 로그인 세션이 쓰이고, 아직 해당 세션을 구현 안했으니까 주석처리를 했어요. 그런데 생각해보니 어차피 cookie의 name은 jsessionid로 동일할테니 주석 해제해도 되겠네요!
그런데 description은 우리가 기존의 비회원용 reviewGroupSession과 새로 생길 회원용 로그인 session을 구분하지 않고 동일하게 세션 ID로 써도 될까 고민입니다. 프론트에게 비회원 리뷰 그룹 세션 ID / 회원용 로그인 세션 ID 이렇게 구분하지 않아도 될까요?
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.
그런데 생각해보니 어차피 cookie의 name은 jsessionid로 동일할테니 주석 해제해도 되겠네요!
😁👍
api 문서에서도 이를 드러낼 수 있게 수정 부탁해요~
그리고 jsessionid 를 회원/비회원 모두 사용해도 되는지에 대한 제 의견은,
저는 동일하게 jsession id 를 사용해도 된다고 생각해요. 그게 오히려 복잡도를 줄일 것 같고, 백엔드 코드에서 별도의 객체를 만들어서 권한을 관리하면 된다 생각했어요.
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.
반완!
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.
@skylar1220 의견 남겼는데 확인 부탁합니다.
- 의견 통일되면 반영하고 검토받고,
- 갈린다면 디코 스레드에서 투표하는걸로 합시다요
@@ -39,6 +40,13 @@ public ResponseEntity<Void> createReview(@Valid @RequestBody ReviewRegisterReque | |||
return ResponseEntity.created(URI.create("/reviews/" + savedReviewId)).build(); | |||
} | |||
|
|||
@PostMapping("/v2/reviews/member") | |||
public ResponseEntity<Void> createReviewByMember(@Valid @RequestBody ReviewRegisterRequest request) { | |||
// 회원 세션 추후 추가해야 함 |
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.
다시 보니, 이 api는 /v2/reviews api 하나로 처리해도 상관없어 보여요.
- 세션 유무에 따라서 내부 로직은 분기하면 됩니다.
- 근데 요청 dto가 동일한데, 세션을 받아야 하는 이유가 있었나요? (생각이 안납니다..)
@@ -75,4 +83,15 @@ public ResponseEntity<ReviewsGatheredBySectionResponse> getReceivedReviewsBySect | |||
reviewGatheredLookupService.getReceivedReviewsBySectionId(reviewGroup, sectionId); | |||
return ResponseEntity.ok(response); | |||
} | |||
|
|||
@GetMapping("/v2/written") |
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.
이 api의 url에서 "written"만 있는 것은 어떤 자원을 찾는지 명확하지 않아보여서 변경이 필요해 보이네요.
- 기존 보완 -> /reviews/written
- 신초의 의견을 반영한 authored 사용 -> /reviews/authored
- 특정 회원의 작성된 리뷰 목록 -> /users/{userId}/written-reviews (세션과 id 검증 필요)
} | ||
|
||
@PostMapping("/v2/groups/member") | ||
public ResponseEntity<ReviewGroupCreationResponse> createReviewGroup( |
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.
요것도 마찬가지로 groups랑 합칠 수 있을 것 같습니다
- 세션 유무에 따른 분기처리
🚀 어떤 기능을 구현했나요 ?
다음과 같은 API 문서를 작성했습니다.
🔥 어떻게 해결했나요 ?
-> 회원이 생성한 리뷰 그룹인 경우, 회원ID가 함께 제공
-> 비회원이 생성한 리뷰 그룹인 경우, 회원ID는 null로 제공
클라이언트는 회원 ID가 null인 경우 비회원의 그룹으로 판단할 수 있고, ID가 존재하는 경우 로그인 사용자의 ID와 비교하여 리뷰 그룹의 주인인지를 확인하면 됩니다.
[백엔드 추가 전달 사항]
📝 어떤 부분에 집중해서 리뷰해야 할까요?
📚 참고 자료, 할 말