-
Notifications
You must be signed in to change notification settings - Fork 169
[Spring Core]서현진 8,9,10단계 제출합니다. #531
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: nonactress
Are you sure you want to change the base?
Conversation
|
해윤님의 답변을 보고 제가 멱등성 키를 왜 사용하려 했는지 그 본질을 생각해보게 하는 질문이여서 생각을 정리해보았습니다! 리뷰어님의 답변을 두개의 질문으로 정리해 볼 수 있을 것 같습니다!
제가 상정했던 상황을 설명하며 코드 로직의 배경을 설명해 보겠습니다!! 1) 네트워크 연결 불안정 시나리오만약 서버가 요청을 받아 db에 저장하고 나서 클라이언트에게 “성공했다”는 응답을 보내려는 찰나에 네트워크가 끊긴다면 클라이언트는 응답을 못받았다고 생각하고 다시 요청을 시도 할 것이고 이를 막아주는 것이 멱등성 키이다 라고 생각하고 코드 로직을 짜보았습니다. 2) uuid는 생성시마다 달라지는데…???사용자의 요청을 받은 프론트엔드에서 생성된 uuid가 서버로 post 요청을 보냈을 때 네트워크 오류가 난다면 다시 프론트엔드에서 다시 서버로 전송하려고 할때 똑같은 멱등성 키를 사용하여 같은 요청에 대해 처리를 하기 위해서 위와 같은 코드 구성을 해보았습니다! 3) Repository 중복 체크 vs 멱등성 키repository에서 |
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.
사용자의 요청을 받은 프론트엔드에서 생성된 uuid가 서버로 post 요청을 보냈을 때 네트워크 오류가 난다면 다시 프론트엔드에서 다시 서버로 전송하려고 할때 똑같은 멱등성 키를 사용하여 같은 요청에 대해 처리를 하기 위해서 위와 같은 코드 구성을 해보았습니다!
꼼꼼하게 여러 케이스들을 고민해주셨군요!
저도 해당 경우에 익숙하지 않아 질문을 하나 드리려합니다
사용자의 요청을 받은 프론트엔드에서 생성된 uuid가 서버로 post 요청을 보냈을 때 네트워크 오류가 난다면 다시 프론트엔드에서 다시 서버로 전송하려고 할때 똑같은 멱등성 키를 사용하여 같은 요청에 대해 처리를 하기 위해서 위와 같은 코드 구성을 해보았습니다!
똑같은 멱등성 키를 사용하여 같은 요청에 대해 처리를 하는 부분은 어디에있나요?!
| @Autowired | ||
| public ReservationService(ReservationRepository reservationRepository, | ||
| IdempotencyRepository idempotencyRepository | ||
| IdempotencyRepository idempotencyRepository, | ||
| TimeRepository timeRepository | ||
| ) { | ||
| this.reservationRepository = reservationRepository; | ||
| this.idempotencyRepository = idempotencyRepository; | ||
| this.timeRepository = timeRepository; | ||
| } |
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.
생성자가 하나뿐일 때 는 @Autowired 를 생략할 수 있습니다!
또한 final필드만 생성자를 만들어주는 어노테이션이 있는데요 학습해보셔도 좋을 것 같습니다!
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.
@RequiredArgsConstructor : final 필드만 생성자를 만들어주는 어노테이션
장점
1)의존하는 Repository가 늘어나거나 줄어들 때마다 생성자를 수정할 필요가 없습니다. 필드만 추가/삭제하면 끝!
2) final 키워드를 강제하므로, 객체가 생성된 후에 의존성이 변경되는 것을 막아줍니다.
적용 커밋 : db68a06
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.
에러 코드를 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.
장점
-
비즈니스 로직과 HTTP 상태의 분리
서비스 계층(Service)와 웹 계층(Controller, HTTP Status) 분리를 하게 되면 서비스는 예약이 중복되었단 사실만 enum에서 받아올 수 있고GlobalExceptionHandler에서 400,409 인지 결정하기 때문에 유지보수 관점에서도 좋습니다! -
유지보수의 편의성
이전 구조에선 에러 메세지를 수정할 때 모든 파일들을 찾아가면 에러를 수정해야했는데 이젠ErrorCode만 확인하면 되니 편합니다! -
하드코딩 방지 및 타입 안정성
ErrorCode.RESERVATOIN_DUPLICATED(오타 발생 시) -> 컴파일 에러가 발생하여 실행 전에 즉시 수정 가능합니다!
| ) | ||
| { | ||
| Map<String, String> error = new HashMap<>(); | ||
| error.put("message", "이미 예약이 존재하는 시간은 삭제할 수 없습니다."); |
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.
이 부분도 ErrorCode 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.
enum에서 관리하는 것이 훨씬 좋은 것 같습니다. 적용해보겠습니다!
적용 커밋 : ecfb3eb
| if (reservationRepository.existsByDateAndTime(request.date(), time.getId())) { | ||
| throw new IllegalArgumentException("이미 예약된 시간입니다!"); | ||
| } |
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.
해당 경우의 에러 메세지도 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.
적용해보겠습니다!!
적용 커밋 : ecfb3eb
| public Reservation get(ReservationCreateRequest request) { | ||
| return reservationRepository.get(request.name(), request.date(), request.time()); | ||
| if (count == 0) { | ||
| throw new IllegalArgumentException("삭제할 예약을 찾을 수 없습니다."); |
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.
넵 수정해 보겠습니다!
적용 커밋 : ecfb3eb
| public boolean exitsById(Long id) | ||
| { | ||
| String sql= "SELECT count(*) FROM time WHERE id = ?"; | ||
| Integer count = jdbcTemplate.queryForObject(sql, Integer.class, id); | ||
| return count != null && count > 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.
해당 메서드는 어디에서 사용되나요??
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.
아 원래 TimeService의 deleteTime에서 존재 여부 확인 후 삭제 하려고 만들어놓은 코드였는데 적용을 확인을 못하고 넘어 간 것 같습니다. 적용해보겠습니다!!
적용 커밋 : b5c11d7
멱등성 처리 로직은
기존 적용 커밋 : 77083a4 |


안녕하세요! 남해윤 리뷰어님! 리뷰어-리뷰이로 만나는 것은 처음인 것 같습니다.
잘 부탁드립니다 :)
🔹 예약 생성 로직 개선 (멱등성 + 동시성 의도)
보내지 않은 경우에는 Controller에서 UUID를 생성하여 요청을 식별하도록 했습니다.
❓궁금한 점
동시 요청 처리
멱등성 설계