Skip to content

[πŸš€ 사이클2 - λ―Έμ…˜ (μ˜ˆμ•½ λ³€κ²½/μ·¨μ†Œμ™€ μ—λŸ¬ 처리)] μ£Όλ‹ˆ(이해선) λ―Έμ…˜ μ œμΆœν•©λ‹ˆλ‹€. #433

Open
haeseonlee wants to merge 13 commits into
woowacourse:haeseonleefrom
haeseonlee:haeseonlee
Open

Conversation

@haeseonlee
Copy link
Copy Markdown

@haeseonlee haeseonlee commented May 13, 2026

μ•ˆλ…•ν•˜μ„Έμš”. 에코!

사이클2도 잘 λΆ€νƒλ“œλ¦½λ‹ˆλ‹€. 😊

체크 리슀트

  • λ―Έμ…˜μ˜ ν•„μˆ˜ μš”κ΅¬μ‚¬ν•­μ„ λͺ¨λ‘ κ΅¬ν˜„ν–ˆλ‚˜μš”?
  • Gradle testλ₯Ό μ‹€ν–‰ν–ˆμ„ λ•Œ, λͺ¨λ“  ν…ŒμŠ€νŠΈκ°€ μ •μƒμ μœΌλ‘œ ν†΅κ³Όν–ˆλ‚˜μš”?
  • μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ •μƒμ μœΌλ‘œ μ‹€ν–‰λ˜λ‚˜μš”?

베이슀 μ½”λ“œ 선택 체크

  • 이전 λ―Έμ…˜μ˜ λ‚΄ μ½”λ“œμ—μ„œ μ‹œμž‘
  • 이전 λ―Έμ…˜μ˜ νŽ˜μ–΄μ˜ μ½”λ“œμ—μ„œ μ‹œμž‘

μ–΄λ–€ 뢀뢄에 μ§‘μ€‘ν•˜μ—¬ 리뷰해야 ν• κΉŒμš”?

μ‚¬μš©μž 본인 μ˜ˆμ•½ λ³€κ²½ 및 μ·¨μ†Œ API

λ©”μ„œλ“œ URL μ„€λͺ… 성곡 응닡
DELETE /reservations/{id} μ˜ˆμ•½ μ·¨μ†Œ 204
PATCH /reservations/{id} μ˜ˆμ•½ λ‚ μ§œ 및 μ‹œκ°„ λ³€κ²½ 200

μ—λŸ¬ 응닡 섀계

μ—λŸ¬ μΌ€μ΄μŠ€

상황 μƒνƒœμ½”λ“œ
쀑볡 μ˜ˆμ•½ 409 Conflict
μ§€λ‚˜κ°„ λ‚ μ§œ μ˜ˆμ•½ 400 Bad Request
μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” λ¦¬μ†ŒμŠ€ 404 Not Found
μ˜ˆμ•½μ΄ μ‘΄μž¬ν•˜λŠ” μ‹œκ°„/ν…Œλ§ˆ μ‚­μ œ 400 Bad Request
μœ νš¨ν•˜μ§€ μ•Šμ€ μž…λ ₯κ°’ 400 Bad Request

μ—λŸ¬ 응닡 섀계

GlobalExceptionHandler 클래슀 생성
κΈ°μ‘΄μ—λŠ” μ˜ˆμ™Έ ν΄λž˜μŠ€μ— @ResponseStatusλ₯Ό λΆ™μ΄λŠ” λ°©μ‹μœΌλ‘œ μ—λŸ¬ 응닡을 μ²˜λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€. 이 방식은 μƒνƒœμ½”λ“œλŠ” μ§€μ •ν•  수 μžˆμ§€λ§Œ, 응닡 본문을 μ œμ–΄ν•  수 μ—†μ–΄ Spring κΈ°λ³Έ μ—λŸ¬ νŽ˜μ΄μ§€(HTML)κ°€ κ·ΈλŒ€λ‘œ λ…ΈμΆœλ˜λŠ” λ¬Έμ œκ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€. 특히
IllegalArgumentException처럼 @ResponseStatusκ°€ μ—†λŠ” μ˜ˆμ™ΈλŠ” 500으둜 μ‘λ‹΅λ˜μ–΄ μ‚¬μš©μžμ—κ²Œ μ„œλ²„ λ‚΄λΆ€ 였λ₯˜κ°€ κ·ΈλŒ€λ‘œ λ…ΈμΆœλμŠ΅λ‹ˆλ‹€.

이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ @RestControllerAdviceλ₯Ό μ‚¬μš©ν•œ GlobalExceptionHandlerλ₯Ό λ„μž…ν•˜μ—¬ λͺ¨λ“  μ—λŸ¬ 응닡을 μ•„λž˜ ν˜•μ‹μ˜ JSON으둜 ν†΅μΌν–ˆμŠ΅λ‹ˆλ‹€.

{
  β€œstatus”: INVALID_DATE,
  β€œmessage”: β€œμ§€λ‚˜κ°„ λ‚ μ§œμ—λŠ” μ˜ˆμ•½ν•  수 μ—†μŠ΅λ‹ˆλ‹€.”
}

haeseonlee added 13 commits May 12, 2026 16:15
@echo724 echo724 self-requested a review May 13, 2026 17:10
@echo724 echo724 assigned echo724 and unassigned echo724 May 13, 2026
@echo724
Copy link
Copy Markdown

echo724 commented May 13, 2026

μ•ˆλ…•ν•˜μ„Έμš” μ£Όλ‹ˆ! 이번 PR μ½”λ“œ 변경사항에 μ—†λŠ” ν”Όλ“œλ°± 여기에닀가 적어두도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€!

  • ReservationTimeRequest
    1. λ‹€λ₯Έ Request/Response ν΄λž˜μŠ€λ“€λ„ λ§ˆμ°¬κ°€μ§€μΈλ°, 도메인 디렉토리에 μžˆλ„€μš”..? μ„œλΉ„μŠ€ κ³„μΈ΅μ—μ„œ μ‚¬μš©λ˜κ³  λ”°λ‘œ λΉ„μ§€λ‹ˆμŠ€ λ‘œμ§μ€ μ—†λŠ” κ²ƒμœΌλ‘œλ³΄μ΄λŠ”λ° μ„œλΉ„μŠ€μ— 더 κ°€κΉŒμš΄ ν΄λž˜μŠ€λ“€ μ•„λ‹κΉŒμš”?
    2. μƒμ„±μžμ—μ„œ @JsonFormat μ–΄λ…Έν…Œμ΄μ…˜μ΄ λ“€μ–΄κ°€μžˆλ„€μš”? JSON Format은 API 계측과 κ΄€λ ¨λœ 것 같은데 λ‹€λ₯Έ 곳에 검증 ν¬μΈνŠΈκ°€ μžˆμ–΄μ•Όν•˜μ§€ μ•Šμ„κΉŒμš”?
    3. λ§Œμ•½ 빈 λ°”λ””λ‘œ /admin/times둜 μš”μ²­ν•  경우, λ”°λ‘œ 검증이 μ—†μ–΄μ„œ NullPointException이 뜨고 500μ—λŸ¬κ°€ λœ¨λ„€μš”!

Copy link
Copy Markdown

@echo724 echo724 left a comment

Choose a reason for hiding this comment

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

λ°˜κ°‘μŠ΅λ‹ˆλ‹€ μ£Όλ‹ˆ!
사이클 2 λΉ λ₯΄κ²Œ κ΅¬ν˜„ν•΄μ£Όμ…¨λ„€μš”! 고생 λ§Žμ•˜μŠ΅λ‹ˆλ‹€~
λŒ€λΆ€λΆ„μ˜ μš”κ΅¬μ‚¬ν•­κ³Ό μ˜ˆμ™Έ 상황 ν…ŒμŠ€νŠΈ 잘 μž‘μ„±ν•΄μ£Όμ…¨λ„€μš”! μ μ ˆν•˜κ²Œ μ»€μŠ€ν…€ μ˜ˆμ™Έμ™€ λ©”μ„Έμ§€λ‘œ μ—λŸ¬ 상황을 μœ μ €μ—κ²Œ 잘 μ „λ‹¬ν–ˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.
일단 남긴 μ»€λ©˜νŠΈλ“€ μ€‘μ—μ„œ μ’€ 더 ν™•μΈν•΄μ£Όμ…¨μœΌλ©΄ ν•˜λŠ” 뢀뢄은:

  1. λŒ€λΆ€λΆ„μ˜ κ²½μš°μ—λŠ” μ»€μŠ€ν…€ μ˜ˆμ™Έμ™€ ν•Έλ“€λŸ¬λ‘œ μ²˜λ¦¬ν•΄μ£Όμ…¨λŠ”λ° 500 μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” 뢀뢄이 μžˆμŠ΅λ‹ˆλ‹€! 컀멘트 λΆ€λΆ„ 말고도 ν˜Ήμ‹œ λ†“μΉœ 뢀뢄이 μžˆμ„ 수 μžˆμ„μ§€ κ³ λ―Όν•΄λ³΄μ‹œλ©΄ 쒋을 것 κ°™μ•„μš”. ν”„λ‘œλ•μ…˜ ν™˜κ²½μ—μ„œ 500 μ—λŸ¬λ§ŒνΌ λ¬΄μ„œμš΄κ²Œ μ—†μŠ΅λ‹ˆλ‹€ γ… 
  2. μ˜ˆμ•½μ‹œ λ‚ μ§œμ— λŒ€ν•œ 검증은 잘 ν•΄μ£Όμ…¨λŠ”λ° μ§€λ‚˜κ°„ μ‹œκ°„μ— λŒ€ν•œ 검증은 μ—†λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€! ν•΄λ‹Ή μΌ€μ΄μŠ€ 검증과 ν…ŒμŠ€νŠΈ μΆ”κ°€ν•΄μ£Όμ„Έμš”~
  3. μ˜ˆμ•½ μ·¨μ†Œ 상황에 λŒ€ν•œ 검증이 λΆ€μ‘±ν•©λ‹ˆλ‹€! ν™•μΈν•΄μ£Όμ‹œλ©΄ 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€~
  4. μ˜ˆμ™Έ 상황에 λŒ€ν•œ controller/e2e ν…ŒμŠ€νŠΈκ°€ λΆ€μ‘±ν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.
  5. λ§ˆμ§€λ§‰μœΌλ‘œ 404 HTTP status code에 λŒ€ν•œ 의견 λ‚¨κ²¨μ£Όμ‹œλ©΄ 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€!

ν™•μΈν•΄λ³΄μ‹œκ³  ν˜Ήμ‹œ μ΄ν•΄ν•œλ˜μ‹œκ±°λ‚˜ μ„€λͺ…이 더 ν•„μš”ν•œ λΆ€λΆ„ μžˆμœΌμ‹œλ©΄ μ»€λ©˜νŠΈλ‚˜ λ©”μ„Έμ§€ λ‚¨κ²¨μ£Όμ„Έμš”~ ν™”μ΄νŒ…μž…λ‹ˆλ‹€!

Comment on lines 64 to +65
if (reservationReq.date().isBefore(LocalDate.now())) {
throw new IllegalArgumentException("ν˜„μž¬λ³΄λ‹€ μ΄μ „μ˜ λ‚ μ§œλŠ” μ˜ˆμ•½ν•  수 μ—†μŠ΅λ‹ˆλ‹€.");
throw new InvalidReservationException();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

μ§€λ‚˜κ°„ λ‚ μ§œΒ·μ‹œκ°„μ— λŒ€ν•œ μ˜ˆμ•½ 생성은 λΆˆκ°€λŠ₯ν•˜λ‹€.

μš”κ΅¬μ‚¬ν•­λŒ€λ‘œλ©΄ μ‹œκ°„λ„ 검증을 ν•΄μ•Όν•  것 κ°™μ•„μš”!

Copy link
Copy Markdown
Author

@haeseonlee haeseonlee May 14, 2026

Choose a reason for hiding this comment

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

μ§€λ‚˜κ°„ μ‹œκ°„μ— λŒ€ν•΄μ„œλ„ 검증 λ‘œμ§μ„ μΆ”κ°€ν•˜μ˜€μŠ΅λ‹ˆλ‹€!

ReservationServiceμ—μ„œ ν˜„μž¬ λ‚ μ§œμ΄λ©΄μ„œ ν˜„μž¬ μ‹œκ°„λ³΄λ‹€ 이전인 λ‚ μ§œλ₯Ό 선택할 경우 InvalidReservationException이 λ°œμƒν•˜λ„λ‘ λ¦¬νŒ©ν„°λ§ ν›„ ν…ŒμŠ€νŠΈ μ½”λ“œλ„ μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

Comment on lines +96 to 99

public void delete(Long id) {
reservationUpdatingDao.delete(id);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

λ³€κ²½Β·μ·¨μ†Œ μ‹œ λ°œμƒν•˜λŠ” μ—λŸ¬ μΌ€μ΄μŠ€(이미 μ§€λ‚œ μ˜ˆμ•½μ„ μ·¨μ†Œ, λ³€κ²½ν•˜λ €λŠ” μ‹œκ°„μ΄ 이미 μ°¨ 있음 λ“±)도 2λ‹¨κ³„μ˜ κ·œμΉ™μ— 맞좰 μ²˜λ¦¬ν•œλ‹€.

이번 사이클 μš”κ΅¬μ‚¬ν•­μ—μ„œ μ·¨μ†Œ μΌ€μ΄μŠ€μ—¬λ„ 검증을 ν•΄μ€˜μ•Όν•  것 같은데 μ–΄λ–€ 검증이 μžˆμ„ 수 μžˆμ„κΉŒμš”?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

λ˜ν•œ μ˜ˆμ•½ μ·¨μ†Œ = μ‚­μ œμΈμ§€λ„ κ³ λ―Όν•΄λ³΄μ‹œλ©΄ 쒋을 것 κ°™μ•„μš”! 닡이 μžˆλŠ”κ±΄ μ•„λ‹ˆμ§€λ§Œ λΉ„μ§€λ‹ˆμŠ€μ μœΌλ‘œ μ·¨μ†Œν• λ•Œ μ˜ˆμ•½μ„ μ‚­μ œν•˜λŠ” 경우 μ–΄λ–€ 영ν–₯이 μžˆμ„ 수 μžˆμ„κΉŒμš”?

Comment on lines +84 to +86
if (reservationReq.date().isBefore(LocalDate.now())) {
throw new InvalidReservationException();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

여기도 λ§ˆμ°¬κ°€μ§€λ‘œ μ‹œκ°„μ΄ μ§€λ‚¬λŠ”μ§€μ— λŒ€ν•œ 검증이 ν•„μš”ν•  것 κ°™μŠ΅λ‹ˆλ‹€!


public ReservationResponse update(Long id, ReservationRequest reservationReq) {
Reservation existedReservation = reservationQueryingDao.findReservationById(id)
.orElseThrow(() -> new ReservationNotFoundException(id));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

HTTPμ—μ„œ 404κ°€ NotFound의 의미이긴 ν•˜μ§€λ§Œ, 상황에 따라 두 κ°€μ§€ λ‹€λ₯Έ 상황이 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. ν˜Ήμ‹œ μ–΄λ–€ 상황듀이 μžˆλŠ”μ§€ μ•„μ‹€κΉŒμš”? 힌트둜 λΈŒλΌμš°μ €μ—μ„œ μ‘΄μž¬ν•˜μ§€ μ•Šμ•˜λŠ” URL을 μž…λ ₯ν–ˆμ„λ•Œμ™€ μœ„μ˜ μ½”λ“œμ™€μ˜ μ°¨μ΄λŠ” λ¬΄μ—‡μΌκΉŒμš”?

}

@Test
void μ˜ˆμ•½_λ‚ μ§œ_μ‹œκ°„_λ³€κ²½() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

μ˜ˆμ•½μ‹œ μ˜ˆμ•½ μ˜ˆμ™Έ 상황듀 ν…ŒμŠ€νŠΈκ°€ λΆ€μ‘±ν•œ 것 κ°™μŠ΅λ‹ˆλ‹€!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Timeκ³Ό Theme κ΄€λ ¨ μ˜ˆμ™Έ 상황듀도 ν…ŒμŠ€νŠΈκ°€ 많이 λΆ€μ‘±ν•œ 것 κ°™λ„€μš” γ… 

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

μ„œλΉ„μŠ€ κ³„μΈ΅μ—μ„œ 컀버가 됐닀 ν•˜λ”λΌλ„ μ˜ˆμ™Έ μƒν™©μ—μ„œ μ˜λ„ν•œ 메세지와 μ˜ˆμ™Έμ½”λ“œκ°€ λ°˜ν™˜λλŠ”μ§€λ„ ν™•μΈν•΄μ•Όν•˜μ§€ μ•Šμ„κΉŒμš”?


public class ReferencedDataException extends RuntimeException {
public ReferencedDataException() {
super("μ°Έμ‘° 쀑인 데이터가 μžˆμ–΄ μ‚­μ œν•  수 μ—†μŠ΅λ‹ˆλ‹€.");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

μœ μ € ν˜Ήμ€ ν΄λΌμ΄μ–ΈνŠΈ μž…μž₯μ—μ„œ DB ν…Œμ΄λΈ” ꡬ쑰λ₯Ό λͺ¨λ₯΄λŠ” μƒν™©μ—μ„œ μ°Έμ‘° 쀑인 λ°μ΄ν„°λΌλŠ”κ²Œ μ–΄λ–€ 데이터λ₯Ό μ˜λ―Έν•˜λŠ”μ§€ λͺ¨λ₯Ό 수 μžˆμ„ 것 κ°™μ•„μš”.

Comment on lines +18 to 37
throw new InvalidInputException("이름은 ν•„μˆ˜μž…λ‹ˆλ‹€.");
}
}

private static void validateDate(LocalDate date) {
if (date == null) {
throw new IllegalArgumentException("λ‚ μ§œλŠ” ν•„μˆ˜μž…λ‹ˆλ‹€.");
throw new InvalidInputException("λ‚ μ§œλŠ” ν•„μˆ˜μž…λ‹ˆλ‹€.");
}
}

private static void validateTimeId(Long timeId) {
if (timeId == null) {
throw new IllegalArgumentException("μ‹œκ°„μ€ ν•„μˆ˜μž…λ‹ˆλ‹€.");
throw new InvalidInputException("μ‹œκ°„μ€ ν•„μˆ˜μž…λ‹ˆλ‹€.");
}
}

private static void validateThemeId(Long themeId) {
if (themeId == null) {
throw new IllegalArgumentException("ν…Œλ§ˆλŠ” ν•„μˆ˜μž…λ‹ˆλ‹€.");
throw new InvalidInputException("ν…Œλ§ˆλŠ” ν•„μˆ˜μž…λ‹ˆλ‹€.");
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

μ•„λ¬΄λž˜λ„ Request Body의 ν•„λ“œ 값듀에 λŒ€ν•œ κ²€μ¦μ΄λ―€λ‘œ ν•„λ“œ 이름을 κ·ΈλŒ€λ‘œ λ„£μ–΄μ£ΌλŠ”κ²Œ λ‚˜μ„ 것 κ°™μ•„μš”. 예λ₯Ό λ“€μ–΄ μ‹œκ°„μ΄λΌκ³ λ§Œ ν•˜λ©΄ μ–΄λ–€ μ‹œκ°„ 값을 μ•ˆλ„£μ€κ±΄μ§€, μ•„λ‹ˆλ©΄ timeIdλ₯Ό λ„£μ§€ μ•Šμ€κ±΄μ§€ ν—·κ°ˆλ¦΄ 수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€. μš”μ²­μ— timeId ν•„λ“œκ°€ λΉ„μ–΄μžˆμŠ΅λ‹ˆλ‹€ μ΄λŸ°μ‹μœΌλ‘œμš”.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

μΆ”κ°€μ μœΌλ‘œ, λ§Œμ•½ μ—¬λŸ¬ ν•„λ“œ 값이 μ—†λŠ” 경우, μ—¬λŸ¬ 번의 μš”μ²­μ„ ν†΅ν•΄μ„œ μ•Œ 수 μžˆμ„ν…λ° λͺ¨λ‘ λͺ¨μ•„μ„œ ν•œ λ²ˆμ— μ•Œλ €μ£ΌλŠ” 방식은 μ–΄λ–¨κΉŒμš”? 예λ₯Ό λ“€μ–΄, "[timeId, themeId]κ°€ λΉ„μ–΄μžˆμŠ΅λ‹ˆλ‹€."μ΄λŸ°μ‹μœΌλ‘œμš”. 그러면 μœ μ €κ°€ μ—¬λŸ¬ 번의 μš”μ²­ 없이 ν•œ λ²ˆμ— μ•Œ 수 있겠죠? μ–΄λ–»κ²Œ μƒκ°ν•˜μ‹œλ‚˜μš”?

Comment on lines +42 to +44
public Reservation withUpdatedDateAndTime(LocalDate date, ReservationTime time) {
return new Reservation(id, this.name, date, time, this.theme, this.createdAt);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

κ°€λ…μ„±μžˆκ³  λͺ…μ‹œμ μΈ λ©”μ„œλ“œ 잘 μž‘μ„±ν•΄μ£Όμ…¨λ„€μš”! λ‹€λ§Œ, μœ„μ˜ λ©”μ„œλ“œ 이름은 reservationWithId인데, 이 λ‘˜μ˜ λ©”μ„œλ“œ 이름이 일관성이 κΉ¨μ§„ 것 κ°™μŠ΅λ‹ˆλ‹€. λΉ„μŠ·ν•œ ν–‰μœ„λ₯Ό ν•˜λŠ” 것 같은데 with**으둜 ν†΅μΌν•˜λŠ” 것은 μ–΄λ–¨κΉŒμš”?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants