inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[인프런 워밍업 클럽 3기 / 백엔드 프로젝트] 3주차 정리

와땅깡
0

공부 내용 정리

이번주에는 GET 요청을 제외한 나머지의 요청들을 개발 (어드민 서비스)에 대해 공부하고 이에 Exception에 일관성있게 처리가능하도록 하는 법을 배웠습니다.

그래서 이번 글에서는 Exception 처리에 대해서 정리해보았습니다.

 

커스텀 예외처리 순서

1. 커스텀 예외 클래스 계층 정의

2. 각 예외 상황에 맞는 구체적인 커스텀 예외 클래스 생성

3. 예외 발생 시 @RestControllerAdvice를 통해 공통적으로 처리

4. 적절한 HTTP 상태 코드와 메시지를 클라이언트에게 반환

 

이러한 구조를 통해 비즈니스 로직에서 의미 있는 예외를 던지고, 사용자에게 명확한 메시지와 상태 코드로 응답할 수 있었습니다.

 

내용

abstract class MementoCapsException

 

class MementoCapsNotFoundException(message: String)

class PresentationApiControllerAdvice

 

미션 5

미션 5는 삽입, 수정, 삭제 REST API를 만들어 각각 테스트케이스를 3개 이상씩 만들어 제출하는 것 이였습니다.

 

해당 프로젝트에서는 중심적인 데이터 베이스 엔티티의 관계가 N:M 관계로 이루어져있었습니다.

따라서 중간에 연결 테이블 엔티티가 존재했습니다.

 

그래서 처음 저장 로직을 작성할때 다음과 같은 고민이 생겼습니다.

 

문제 상황

타임캡슐을 처음 생성하면 해당 캡슐의 작성자가 OWNER 로써 관계 테이블 (User_Capsule)에 등록되어야 했습니다.

즉 타임캡슐 테이블 데이터 생성과 동시에 작성자_캡슐 테이블의 데이터도 저장되어야 했습니다.

이때 처음에는 Capsule 엔티티에서 생성자 파라미터로 writer: User를 넘긴 뒤, 내부에서 작성자 정보를 UserCapsule로 매핑하는 방식을 사용했습니다.

하지만 실제로 제가 설계한 테이블은 Capsule 엔티티에는 writer 필드가 존재하지 않고, UserCapsule(role = OWNER)로만 작성자를 식별하는 구조였기에 구조와 맞지않고, 엔티티의 책임이 커진다는 느낌을 받아 수정해보았습니다.

 

해결 방법

UserCapsule은 capsule.id, user.id가 모두 필요한 관계이므로

캡슐을 먼저 저장 → 관계를 이후에 저장하는 방식이 더 명확하다고 판단했습니다.

따라서 변경된 저장 순서는 다음과 같습니다.

캡슐 생성 로직 실행 1. 캡슐 테이블에 (작성자 정보 없이 순수한 캡슐 데이터만 있는) 캡슐 정보 저장 2. 입력받은 작성자 아이디를 가지고 user 테이블에서 user 정보 얻기 3. 저장된 캡슐 데이터에서 방금 작성한 캡슐 정보 얻기 4. 캡슐정보와 유저 정보를 매핑 (Role = OWNER)후 저장

 

이렇게 하게되면 UserCapsuleRepository의 save 로 멤버와 작성자 모두 처리가 가능합니다.

즉 서비스 단에서 "캡슐 저장"이라는 비지니스 로직은 다음과 같이 정의됩니다.

 

이렇게 구조를 바꾸니 멤버를 추가할때도 엔티티의 책임은 덜어내고 비슷한 방식으로 처리가 가능했습니다.

 

이렇게 정립한 의존성 규칙을 유지하며 나머지 기능들도 작성할 수 있었습니다.

 

테스트 코드 작성

테스트 코드는 예외처리에 정의된 부분들에 대해서 테스트 할 수 있었습니다.

  1. 정상적인 데이터 처리 케이스

  2. Vaild에 위반되어 400 에러가 발생하는 케이스

  3. url Path에 들어갈 값을 잘못 전달하여 404에러가 발생하는 케이스

  4. request Body값이 잘못 전달되어 400 에러가 발생하는 케이스

  5. 해당 기능을 허용하지 않는 role을 가진 멤버가 기능을 요청할 경우 403에러를 발생하는 케이스 등

각 기능에 맞게 테스트 케이스를 작성하였습니다.

 

회고

GOOD

PROBLEM

TRY

 

백엔드 인프런 워밍업클럽 백엔드 Spring Kotlin

답변 0