-
Notifications
You must be signed in to change notification settings - Fork 82
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
[2 - 4 단계 방탈출 예약 결제 / 배포] 몰리(김지민) 미션 제출합니다. #102
Conversation
- ReservationRepository 결제에 대해 outer join한 예약 객체 조회 메서드 추가
@@ -19,6 +19,8 @@ dependencies { | |||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' | |||
implementation 'org.springframework.boot:spring-boot-starter-validation' | |||
|
|||
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0' |
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.
문서화 툴로 SpringDoc을 선택한 이유
일단 RestDocs과 SpringDoc을 사용해본 경험이 있습니다. 따라서 두 가지 툴을 고려했었는데요.
제가 생각하기에 RestDocs은 테스트 기반이라 훨씬 신뢰성이 높고, 문서가 깔끔하다고 느꼈었습니다.
반면에 SpringDoc은 테스트를 작성하지 않아도 문서화가 가능하고, API 테스트가 가능하다는 점에서 함께 프로젝트를 했었던 프론트 개발자들이 선호했었던 기억이 컸습니다. 하지만 SpringDoc을 사용하게 되면 프로덕션 코드에 침투적이다 라는 단점이 있었는데요.
문서화를 보는 사람이 누구냐고 했을 때 프론트 개발자라고 생각했고 현재는 프론트 개발자가 없기는 하지만 이번 기회를 통해서 SpringDoc을 더 클린하게 사용할 수 있는 방법을 고민해보고 싶어서 선택하게 되었습니다.
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 문서를 뽑아내야하고, 테스트코드가 불완전한 상황이라면 swagger가 낫고, 그렇지 않다면 restdocs가 더 장점을 가질 수도 있고요ㅎㅎ
그래도 우테코 미션 하는 동안에는 연습이 가장 중점이니, 이미 해보셨다고 하더라도 RestDocs를 활용해서 테스트기반 문서화를 정말 빡세게 해보는 것도 한번쯤 추천드립니당!
@BeforeEach | ||
void setUp() { | ||
mockRestServiceServer = MockRestServiceServer.bindTo(restClientBuilder).build(); | ||
paymentClient = new TossPaymentClient(restClientBuilder.build()); |
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단계 구현 당시 테스트 코드에서 FakeClient를 사용했었는데요.
당시 리뷰 요청을 보낼 때에는 통과가 되었던 것 같은데, 리뷰를 보고 다시 돌려보니 타임아웃 에러가 뜨더라구요. 😅
또, 조앤이 의견 주셨던 것처럼 관리할 수 있는 부분이 아니기도 하고 꼭 실제 요청이 필요한 테스트도 아닌 것 같아, Fake를 고집하는 것보다는 상황에 맞게 Mock을 사용하도록 변경했습니다!
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.
좋네요. 상황에 맞게 적절한 선택을 하는 것도 좋은 경험이라고 생각해요! 💯
import roomescape.common.exception.ForbiddenException; | ||
import roomescape.common.exception.UnAuthorizationException; | ||
import roomescape.payment.client.toss.TossClientErrorResponse; | ||
|
||
@ControllerAdvice | ||
public class GlobalExceptionHandler { | ||
|
||
private static final Logger logger = Logger.getLogger("Logeer"); | ||
private static final Logger logger = Logger.getLogger("Logger"); |
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.
Logging의 범위
현재는 예외 발생 시에만 발생한 메시지 또는 클래스를 로깅하고 있습니다.
외부 Client에 대해서는 요청, 응답 정보에 대한 로깅이 필수적이라고 들어서, 해당 부분에 대해 로깅이 추가적으로 필요할 것 같습니다. 하지만 필수가 아닌 선택 사항이기도 하고 일단 리뷰를 일찍 받고 싶어서 제외했습니다...!
혹시 예외와 외부 Client를 제외하고 조앤이 보시기에 로깅이 더 필요한 부분이 더 있을�지, 혹은 충분할지 궁금합니다 !
(다른 부분에도 로그를 추가한다고 하면 어떤 부분에 필요할지 감이 잘 오지 않는 것 같습니다 🥲)
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.
이 부분은 코드 전체적으로 보면서 추가로 필요한 부분이 있다면 거기에 남겨둘게요!
import roomescape.reservation.model.Reservation; | ||
|
||
@Entity | ||
public class Payment extends BaseEntity { |
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.
Payment 정보를 Reservation 테이블에 저장하지 않고 분리한 이유
만약, 두 테이블을 분리하지 않게 되면 관리자 승인으로 생성된 Reservation의 결제 정보가 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.
payment에는 member에 대한 정보는 없고 reservation만 엮어주신 이유가 궁금해요!
그리고 reservation도 단순히 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.
payment에는 member에 대한 정보는 없고 reservation만 엮어주신 이유가 궁금해요!
payment가 reservation을 가지고 있고 그 reservation이 member를 가지고 있기 때문에 굳이 member에 대해서도 의존 관계를 맺지 않아도 될 것 같다고 생각했습니다 ...!
그리고 reservation도 단순히 id만 연결할 수도 있을 것 같은데 이렇게 구성해주신 이유가 궁금해요!
객체지향 관점에서 봤을 때 id값만 가지고 있기보다는 객체 자체를 알고 가지고 있는 것이 더 자연스럽다고 생각했던 것 같습니다 !
또 연관된 객체의 데이터도 같이 한번에 가지고 올 수 있기 때문에 장점이 크다고 생각했습니다 !
// when & then | ||
assertThatThrownBy(() -> reservationService.createMyReservation(authInfo, createMyReservationRequest)) | ||
.isInstanceOf(ClientException.class); | ||
assertThat(reservationRepository.count()).isZero(); |
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.
조앤 사실 이 부분은 제 예상대로 동작하는 테스트가 아닙니다.🥲
실패한 테스트이지만, 왜 저의 예상대로 동작하지 않는지 이유를 잘 모르겠습니다...
일단 저의 의도는 결제 오류(RuntimeException을 상속)가 발생하게 되면 @Transactional
으로 묶여있는 예약 생성 또한 실패하여 롤백되기를 기대했는데요.
따라서 아래의 코드 (코드에서는 일단 제거) 가 통과되기를 바랬지만 실제 결과는 예약이 저장되어버려서 갯수가 1이 되었습니다...
assertThat(reservationRepository.count()).isZero();
반면 동일한 내용을 테스트하는 통합 테스트에서는 정상적으로 작동이 되었는데요. ReservationIntegrationTest.java
어떠한 부분이 제 예상과 다르게 동작하는지 이유를 모르겠어서 transaction log 를 살펴 보니 아래와 같은 로그가 찍혀있었어요.
Participating transaction failed - marking existing transaction as rollback-only
Setting JPA transaction on EntityManager [SessionImpl(1966387876<open>)] rollback-only
.. 생략
테스트가 깨지는 코드를 여쭤보는 것이 뭔가 리뷰어에 대한 도리가 아닌 것 같아서 이유를 파악하기 위해 여러가지 시도(SpringBootTest로 변경, MockRestServiceServer 로 변경 등등)를 해보았는데, 여전히 저의 의도대로 동작하지 않아 모르겠습니다..
혹시 어떤 부분을 제가 놓친 것인지 여쭤봐도 될까요 ? 😭
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.
이거 디버깅 해보니깐
AbstractPlatformTransactionManager.processRollback 부분 (line 504)에서
IntegrationTest일 때는 status.isNewTransaction()이 true로 나오고, ServiceTest일 때는 status.isNewTransaction()이 false로 나와요!
@DataJpaTest
에서 기본적으로 TX를 설정해줘서 그런건가 싶기도 하네요! 저도 좀 더 알아볼게요!
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.
앗 ! 조앤 말씀처럼 @DataJpaTest
의 @Transactional
로 인해 테스트 메서드 하나가 트랜잭션으로 묶여 관리되어서 테스트가 실패하네요 🥲
해당 테스트 코드를 통과하도록 변경하고 추적을 해보니, 아래처럼 동작했다는 것을 알 수 있었어요 😭
- reservationService의 createMyReservation() 메서드 실행
- 1번 내부에서 호출하는 paymentService의 createPayment에서 예외 발생
➡️ 이때, 트랜잭션에 롤백 마킹만 하고 최종 트랜잭션이 끝나지 않아 롤백은 실행되지 않은 상태 - reservationRepository.count 실행
➡️ 트랜잭션 완료되지 않아 롤백 X ➡️ 예약이 저장되어 있는 상태 - 테스트 메서드 종료
➡️ 최종 트랜잭션 완료 처리 시작 -> 롤백 마킹을 이때 체크하여 롤백
다른 방식으로 변경해보겠습니다 !
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.
안녕하세요 몰리! 이번에도 미션 깔끔하게 잘 수행해주셨네요ㅎㅎ
남겨주신 질문은 저도 좀 더 봐볼게요!
코멘트 소소하게 몇가지 남겨봤어요~
// when & then | ||
assertThatThrownBy(() -> reservationService.createMyReservation(authInfo, createMyReservationRequest)) | ||
.isInstanceOf(ClientException.class); | ||
assertThat(reservationRepository.count()).isZero(); |
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.
이거 디버깅 해보니깐
AbstractPlatformTransactionManager.processRollback 부분 (line 504)에서
IntegrationTest일 때는 status.isNewTransaction()이 true로 나오고, ServiceTest일 때는 status.isNewTransaction()이 false로 나와요!
@DataJpaTest
에서 기본적으로 TX를 설정해줘서 그런건가 싶기도 하네요! 저도 좀 더 알아볼게요!
- 예약 API 변경 | ||
- [x] 예약 요청 시 결제 기능 추가 | ||
- [x] 결제 실패 시 예외 처리 | ||
- [x] 사용자에게 결재 실패 사유 전달 | ||
- [x] 외부 API 연동 | ||
|
||
## 2단계 |
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.
aws에 배포할 때 어떤 프로세스로 진행해주셨는지 과정을 간단히 설명요청드려도 될까요~?
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.
- aws ec2에 인스턴스 생성
- ssh로 원격 터미널에 접속
- 터미널에서 깃헙 레포지토리 pull 받은 후 빌드
- 빌드 완료 후 생성된 jar파일을 애플리케이션 실행 (백그라운드로)
위 과정을 통해 배포 진행했습니다 !
(질문의 의도와 다른 답변이었다면 말씀 부탁드립니다 🙇 )
import roomescape.auth.dto.response.GetAuthInfoResponse; | ||
|
||
@Tag(name = "회원 인증 API") | ||
public interface AuthControllerApi { |
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.
요거 엄청 상세해서 좋긴 한데 굉....장히 관리포인트가 될 것 같아요. 이 부분은 어떻게 생각하시는지 궁금해요! (코멘트에서 SpringDoc을 깔끔하게 쓰고 싶다고 해주시기도 했지만ㅎㅎ)
뭔가 깔끔한 것 vs 관리 포인트가 늘어나는 것과 관련해서는 좀 고민이 되기도 하네요!
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를 제공해야 했던 경험만 있어서 지속적인 관리라는 포인트에 대해서는 깊게 고민해보지 못한 것 같아요 🤔 또 지금 작성된 코드가 처음 목적처럼 깔끔하지도 못한 것 같기도 하구요 😭
좀 더 개선이 필요할 것 같아 고민을 해보고, enum으로 현재의 @ExampleObject
를 덜 복잡하게 변경해서 실패 케이스의 문서화를 개선하는 방식을 떠올렸습니다.
하지만 이 방식 또한 말씀하신 것처럼 enum을 관리하는 비용이 너무 클 것 같고 오히려 직관적이지 못한 것 같기도 해서 이 부분에 대해서는 조금 더 고민해보겠습니다 😭
* <p> | ||
* - 인증 객체는 토큰으로부터 서버에서 추출하므로 요청 파라미터에서 문서를 제거합니다. | ||
*/ | ||
public class AuthOperationCustomizer implements OperationCustomizer { |
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.
@SecurityRequirement
이 붙은 코드는 공통적으로 로그인이 필요한 (= 토큰이 필요한) API 인데요 !
이 토큰 때문에 발생할 수 있는 에러들을 해당하는 API들에 중복적으로 작성하지 않고 커스텀해서 한곳에서 관리하고자 생성했습니다 !
또한 해당 API들에서 파라미터로 있는 AuthInfo 객체는 클라이언트가 요청을 보낸 이후에 토큰으로부터 회원의 인증 정보를 추출하여 생성되는 객체이기 때문에 API 문서에서는 노출할 필요가 없다고 생각했습니다.
때문에 이 파라미터 값에 대해서는 문서화를 적용하지 않고자 해당 객체를 활용했습니다 ...!
} | ||
|
||
@Bean | ||
public RestClient.Builder restClient() { |
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.
👍
@@ -16,12 +16,12 @@ public TossPaymentClient(final RestClient restClient) { | |||
} | |||
|
|||
@Override | |||
public Payment confirm(ConfirmPaymentRequest confirmPaymentRequest) { | |||
public PaymentInfoFromClient confirm(ConfirmPaymentRequest confirmPaymentRequest) { |
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.
요구사항이 추가되어 결제 정보를 DB에 저장하려고 했을 때, 테이블명을 고민하다가 Payment
라는 이름이 적절하다고 생각하여 해당 이름을 가지는 엔티티를 추가하였습니다.
Payment
라는 이름을 사용했던 기존 클래스(현재의 PaymentInfoFromClient
)는 역할이 결제에 대한 도메인이라기 보다는, 외부 클라이언트로부터 단지 응답값을 가져와서 매핑해주는 DTO 라고 생각하여 더 자세하게 수정하고 싶었습니다 ...!
@@ -67,6 +67,30 @@ void findAllByMemberId() { | |||
.containsExactlyInAnyOrder(reservation1, reservation2, reservation3); | |||
} | |||
|
|||
@Test | |||
@DisplayName("동일한 회원인 모든 예약 및 결제 정보를 조회한다.") |
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.
👍
import roomescape.reservation.model.Reservation; | ||
|
||
@Entity | ||
public class Payment extends BaseEntity { |
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.
payment에는 member에 대한 정보는 없고 reservation만 엮어주신 이유가 궁금해요!
그리고 reservation도 단순히 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.
안녕하세요 조앤 !
리뷰 반영하면서 깊게 생각해보지 못했던 부분들이나 놓쳤던 부분들을 질문해주셔서 고민해볼 수 있었습니다 .. ㅎㅎ
생각보다 리뷰 반영이 늦어졌네요 😭
질문
문서화에 대해 고민하면서 궁금해진 포인트가 하나 있습니다 !
문서화할 때, 각 API에 대해 실패 케이스에 대해 발생하는 이유나 반환 메시지를 최대한 자세하게 다 전달하고자 했는데요.
서버에서 제공하는 실패에 대한 상황이나 에러 응답 메시지에 따라서 프론트 입장에서의 에러처리가 수월할 지가 결정된다고 생각했기 때문입니다.
그런데 이번에 Swagger로 문서를 개선해보려고 시도하면서 뭔가 이렇게까지 해야하는 건가 현타(?)가 왔습니다. 다시 생각해보면 문서를 통해 진짜 중요하게 전달해야 하는 것은 어떤 예외가 발생할 수 있을지 상황이고, 또 문서 관리도 중요한데 적절한 수준에서 타협을 하는 것이 맞는 것 같다는 생각도 조금 들었 습니다.
당연히 최대한 자세한 문서화가 적절한 것일까요? 🤔
이번 리뷰도 잘 부탁드립니다 🙇
@@ -16,12 +16,12 @@ public TossPaymentClient(final RestClient restClient) { | |||
} | |||
|
|||
@Override | |||
public Payment confirm(ConfirmPaymentRequest confirmPaymentRequest) { | |||
public PaymentInfoFromClient confirm(ConfirmPaymentRequest confirmPaymentRequest) { |
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.
요구사항이 추가되어 결제 정보를 DB에 저장하려고 했을 때, 테이블명을 고민하다가 Payment
라는 이름이 적절하다고 생각하여 해당 이름을 가지는 엔티티를 추가하였습니다.
Payment
라는 이름을 사용했던 기존 클래스(현재의 PaymentInfoFromClient
)는 역할이 결제에 대한 도메인이라기 보다는, 외부 클라이언트로부터 단지 응답값을 가져와서 매핑해주는 DTO 라고 생각하여 더 자세하게 수정하고 싶었습니다 ...!
// when & then | ||
assertThatThrownBy(() -> reservationService.createMyReservation(authInfo, createMyReservationRequest)) | ||
.isInstanceOf(ClientException.class); | ||
assertThat(reservationRepository.count()).isZero(); |
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.
앗 ! 조앤 말씀처럼 @DataJpaTest
의 @Transactional
로 인해 테스트 메서드 하나가 트랜잭션으로 묶여 관리되어서 테스트가 실패하네요 🥲
해당 테스트 코드를 통과하도록 변경하고 추적을 해보니, 아래처럼 동작했다는 것을 알 수 있었어요 😭
- reservationService의 createMyReservation() 메서드 실행
- 1번 내부에서 호출하는 paymentService의 createPayment에서 예외 발생
➡️ 이때, 트랜잭션에 롤백 마킹만 하고 최종 트랜잭션이 끝나지 않아 롤백은 실행되지 않은 상태 - reservationRepository.count 실행
➡️ 트랜잭션 완료되지 않아 롤백 X ➡️ 예약이 저장되어 있는 상태 - 테스트 메서드 종료
➡️ 최종 트랜잭션 완료 처리 시작 -> 롤백 마킹을 이때 체크하여 롤백
다른 방식으로 변경해보겠습니다 !
* <p> | ||
* - 인증 객체는 토큰으로부터 서버에서 추출하므로 요청 파라미터에서 문서를 제거합니다. | ||
*/ | ||
public class AuthOperationCustomizer implements OperationCustomizer { |
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.
@SecurityRequirement
이 붙은 코드는 공통적으로 로그인이 필요한 (= 토큰이 필요한) API 인데요 !
이 토큰 때문에 발생할 수 있는 에러들을 해당하는 API들에 중복적으로 작성하지 않고 커스텀해서 한곳에서 관리하고자 생성했습니다 !
또한 해당 API들에서 파라미터로 있는 AuthInfo 객체는 클라이언트가 요청을 보낸 이후에 토큰으로부터 회원의 인증 정보를 추출하여 생성되는 객체이기 때문에 API 문서에서는 노출할 필요가 없다고 생각했습니다.
때문에 이 파라미터 값에 대해서는 문서화를 적용하지 않고자 해당 객체를 활용했습니다 ...!
- 예약 API 변경 | ||
- [x] 예약 요청 시 결제 기능 추가 | ||
- [x] 결제 실패 시 예외 처리 | ||
- [x] 사용자에게 결재 실패 사유 전달 | ||
- [x] 외부 API 연동 | ||
|
||
## 2단계 |
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.
- aws ec2에 인스턴스 생성
- ssh로 원격 터미널에 접속
- 터미널에서 깃헙 레포지토리 pull 받은 후 빌드
- 빌드 완료 후 생성된 jar파일을 애플리케이션 실행 (백그라운드로)
위 과정을 통해 배포 진행했습니다 !
(질문의 의도와 다른 답변이었다면 말씀 부탁드립니다 🙇 )
import roomescape.reservation.model.Reservation; | ||
|
||
@Entity | ||
public class Payment extends BaseEntity { |
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.
payment에는 member에 대한 정보는 없고 reservation만 엮어주신 이유가 궁금해요!
payment가 reservation을 가지고 있고 그 reservation이 member를 가지고 있기 때문에 굳이 member에 대해서도 의존 관계를 맺지 않아도 될 것 같다고 생각했습니다 ...!
그리고 reservation도 단순히 id만 연결할 수도 있을 것 같은데 이렇게 구성해주신 이유가 궁금해요!
객체지향 관점에서 봤을 때 id값만 가지고 있기보다는 객체 자체를 알고 가지고 있는 것이 더 자연스럽다고 생각했던 것 같습니다 !
또 연관된 객체의 데이터도 같이 한번에 가지고 올 수 있기 때문에 장점이 크다고 생각했습니다 !
import roomescape.auth.dto.response.GetAuthInfoResponse; | ||
|
||
@Tag(name = "회원 인증 API") | ||
public interface AuthControllerApi { |
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를 제공해야 했던 경험만 있어서 지속적인 관리라는 포인트에 대해서는 깊게 고민해보지 못한 것 같아요 🤔 또 지금 작성된 코드가 처음 목적처럼 깔끔하지도 못한 것 같기도 하구요 😭
좀 더 개선이 필요할 것 같아 고민을 해보고, enum으로 현재의 @ExampleObject
를 덜 복잡하게 변경해서 실패 케이스의 문서화를 개선하는 방식을 떠올렸습니다.
하지만 이 방식 또한 말씀하신 것처럼 enum을 관리하는 비용이 너무 클 것 같고 오히려 직관적이지 못한 것 같기도 해서 이 부분에 대해서는 조금 더 고민해보겠습니다 😭
자세한 문서화가 당연히 가장 좋을 것 같긴 해요ㅎㅎ |
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.
몰리~ 리뷰가 늦어져서 죄송해요ㅠㅠ
restdocs까지 적용해보시다니 대단해요 💯 남겨주신 코멘트에 답변 남겨봤어요.
더 이상 수정할 것은 없어서 이번 단계는 머지할게요~
몇가지 코멘트 남겨두긴 했는데, 한번 추가적으로 고민해보셔도 좋을 것 같아요! 고생 많으셨어요~
snippetsDir = file('build/generated-snippets') | ||
} | ||
|
||
configurations { |
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.
와우 asciidoc으로 전부 변경해주셨군요! 💯
configurations 블럭과 ext는 어떤 역할을 하나요?
ascii 문서는 어떤 순서로 생성되나요~
dependsOn test | ||
} | ||
|
||
bootJar { |
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.
bootJar는 어떤 역할을 해요?
|
||
operation::admin-reservation-integration-test/create-reservation-by-admin[snippets='http-request,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.
말씀주신 것처럼 엄청 상세하게 구분해주셨군요
우선 예외라는 건 이렇게 발생할 것이 예상되는 것들을 먼저 나열하는 형태인 것 같은데, 이렇게 된다면 새로운 예외가 발생할 때마다 또 추가해줘야할까?라는 고민도 드네요.ㅎㅎ
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단계 (진행했던 테스트 코드 관련 수정)
2단계 (예약 생성 시 결제 정보 저장)
3단계 (배포)
4단계 (문서화)
작성한 문서
배포 링크
API 문서
+) 8일 9시 55분 기준 우테코 aws 서버에 문제가 있는 것 같습니다 😭 오전까지는 정상적으로 접속이 되었는데, 전체 크루 서버가 접속이 불가능한 상태네요 ㅠㅠ API 문서는 서버 구동 후 http://localhost:8080/swagger-ui/index.html 로 확인해주셔야 할 것 같습니다 ....
로그인 정보
이번 단계도 잘 부탁드립니다🍀