-
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: GitHub 연동, 자신이 만든 리뷰 그룹 목록 조회 API 문서 작성 #1014
base: develop
Are you sure you want to change the base?
Changes from 6 commits
ebe88bd
7a88257
772589e
98c0fff
cfff7a4
2afa5a2
6a7f683
22827a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
==== 깃허브로 로그인/회원가입 | ||
|
||
operation::github-auth[snippets="curl-request,request-fields,http-response"] | ||
|
||
==== 로그아웃 | ||
|
||
operation::logout[snippets="curl-request,request-cookies,http-response"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
==== 내 프로필 정보 | ||
|
||
operation::my-profile[snippets="curl-request,request-cookies,http-response,response-fields"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package reviewme.auth.controller; | ||
|
||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpSession; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.ResponseCookie; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import reviewme.auth.service.AuthService; | ||
import reviewme.auth.service.dto.GithubCodeRequest; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class AuthController { | ||
|
||
private final AuthService authService; | ||
|
||
@PostMapping("/v2/auth/github") | ||
public ResponseEntity<Void> authWithGithub( | ||
@Valid @RequestBody GithubCodeRequest request, | ||
HttpServletRequest httpRequest | ||
) { | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@PostMapping("/v2/auth/logout") | ||
public ResponseEntity<Void> logout( | ||
HttpServletRequest httpRequest | ||
) { | ||
HttpSession session = httpRequest.getSession(); | ||
session.invalidate(); | ||
nayonsoso marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
ResponseCookie cookie = ResponseCookie.from("JSESSIONID", "") | ||
.path("/") | ||
.maxAge(0) | ||
.secure(true) | ||
.httpOnly(true) | ||
.build(); | ||
|
||
return ResponseEntity | ||
.noContent() | ||
.header(HttpHeaders.SET_COOKIE, cookie.toString()) | ||
.build(); | ||
} | ||
nayonsoso marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package reviewme.auth.service; | ||
|
||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
public class AuthService { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package reviewme.auth.service.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
|
||
public record GithubCodeRequest( | ||
@NotBlank(message = "깃허브 임시 코드를 입력해주세요.") | ||
String code) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package reviewme.member.controller; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import reviewme.member.service.MemberService; | ||
import reviewme.member.service.dto.ProfileResponse; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class MemberController { | ||
|
||
private final MemberService memberService; | ||
|
||
@GetMapping("/v2/members/profile/mine") | ||
public ResponseEntity<ProfileResponse> getProfile() { | ||
ProfileResponse response = memberService.getProfile(); | ||
return ResponseEntity.ok(response); | ||
} | ||
nayonsoso marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package reviewme.member.service; | ||
|
||
import org.springframework.stereotype.Service; | ||
import reviewme.member.service.dto.ProfileResponse; | ||
|
||
@Service | ||
public class MemberService { | ||
|
||
public ProfileResponse getProfile() { | ||
return null; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package reviewme.member.service.dto; | ||
|
||
public record ProfileResponse( | ||
String nickname, | ||
String profileImageUrl | ||
) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package reviewme.reviewgroup.service.dto; | ||
|
||
import java.time.LocalDate; | ||
|
||
public record ReviewGroupDetailResponse( | ||
nayonsoso marked this conversation as resolved.
Show resolved
Hide resolved
|
||
String revieweeName, | ||
String projectName, | ||
LocalDate createdAt, | ||
String reviewRequestCode | ||
) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 오~ 괜찮은데요? 이건 프론트 분들이랑 이야기를 해봐야 할 것 같아요! |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package reviewme.reviewgroup.service.dto; | ||
|
||
import java.util.List; | ||
|
||
public record ReviewGroupListResponse( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 어떤 회원의 그룹 목록인지 확인할 수 있도록 memberId 필드에 추가하는 건 어떻게 생각하시나요? #1017 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 음 이거에 대해서 다시 생각해봤는데, 불필요한 응답 같다고 다시 생각을 바꾸게 되었어요///😔 |
||
boolean isLastPage, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 내가 받은 리뷰와 동일하게 무한스크롤 구현을 생각해서요~ lastReviewId 필드는 필요하지 않을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 그럼 페이징 적용하는 것으로 하겠습니다👍 @Kimprodp There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. @Kimprodp |
||
List<ReviewGroupDetailResponse> reviewGroups | ||
) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package reviewme.api; | ||
|
||
import static org.hamcrest.Matchers.containsString; | ||
import static org.springframework.restdocs.cookies.CookieDocumentation.cookieWithName; | ||
import static org.springframework.restdocs.cookies.CookieDocumentation.requestCookies; | ||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; | ||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; | ||
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.springframework.restdocs.cookies.CookieDescriptor; | ||
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; | ||
import org.springframework.restdocs.payload.FieldDescriptor; | ||
|
||
public class AuthApiTest extends ApiTest { | ||
|
||
@Test | ||
void 깃허브로_인증한다() { | ||
String request = """ | ||
{ | ||
"code": "github_auth_code" | ||
} | ||
"""; | ||
|
||
FieldDescriptor[] requestFieldDescriptors = { | ||
fieldWithPath("code").description("깃허브 임시 인증 코드"), | ||
}; | ||
|
||
RestDocumentationResultHandler handler = document( | ||
"github-auth", | ||
requestFields(requestFieldDescriptors) | ||
); | ||
|
||
givenWithSpec().log().all() | ||
.body(request) | ||
.when().post("/v2/auth/github") | ||
.then().log().all() | ||
.apply(handler) | ||
.statusCode(200); | ||
} | ||
|
||
@Test | ||
void 로그아웃한다() { | ||
CookieDescriptor[] cookieDescriptors = { | ||
cookieWithName("JSESSIONID").description("세션 ID") | ||
}; | ||
|
||
RestDocumentationResultHandler handler = document( | ||
"logout", | ||
requestCookies(cookieDescriptors) | ||
); | ||
|
||
givenWithSpec().log().all() | ||
.cookie("JSESSIONID", "SESSION12345678") | ||
.when().post("/v2/auth/logout") | ||
.then().log().all() | ||
.apply(handler) | ||
.statusCode(204) | ||
.header("Set-Cookie", containsString("JSESSIONID=; Path=/; Max-Age=0")); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package reviewme.api; | ||
|
||
import static org.springframework.restdocs.cookies.CookieDocumentation.cookieWithName; | ||
import static org.springframework.restdocs.cookies.CookieDocumentation.requestCookies; | ||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; | ||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; | ||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.mockito.BDDMockito; | ||
import org.springframework.restdocs.cookies.CookieDescriptor; | ||
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; | ||
import org.springframework.restdocs.payload.FieldDescriptor; | ||
import reviewme.member.service.dto.ProfileResponse; | ||
|
||
public class MemberApiTest extends ApiTest { | ||
|
||
@Test | ||
void 내_프로필을_불러온다() { | ||
BDDMockito.given(memberService.getProfile()) | ||
.willReturn(new ProfileResponse("donghoony", "https://aru.image")); | ||
|
||
CookieDescriptor[] cookieDescriptors = { | ||
cookieWithName("JSESSIONID").description("세션 ID") | ||
}; | ||
|
||
FieldDescriptor[] responseFieldDescriptors = { | ||
fieldWithPath("nickname").description("닉네임"), | ||
fieldWithPath("profileImageUrl").description("프로필 이미지 URL") | ||
}; | ||
|
||
RestDocumentationResultHandler handler = document( | ||
"my-profile", | ||
requestCookies(cookieDescriptors), | ||
responseFields(responseFieldDescriptors) | ||
); | ||
|
||
givenWithSpec().log().all() | ||
.cookie("JSESSIONID", "SESSION12345678") | ||
.when().get("/v2/members/profile/mine") | ||
.then().log().all() | ||
.apply(handler) | ||
.statusCode(200); | ||
} | ||
} |
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.
산초가 올려준 디스커션의 인증 과정중 아래의 1~3번을 이 메서드에서 모두 하는것인지 궁금해요!(아직 구현이 안해서 헷갈려서 물어봅니당)
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.
혹시 이때 사용자 정보나 로그인 정보같은 것은 안내려줘도 괜찮나요?
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.
@Kimprodp
사용자 정보를 따로 넘겨주기보다, 클라이언트와는 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.
정보를 1회성으로 내려주는 게 좋을까요, 프론트에서 정보를 확인할 수 있는 API를 뚫어두는 게 좋을까요?