2024. 10. 1. 19:30ㆍ내일배움캠프
일단 '필수 기능' 에 대한 요구사항을 모두 반영해 구현을 하였지만 아직 해결해야 할 것이 있다. 바로 'Exception Handling(예외 처리)' 에 대한 부분인데, 요구사항에는 명시되어있지 않지만 프로젝트를 구현하면서 필요하다 생각하는 예외에 대한 부분을 처리해볼 생각이다. 이번 내용을 구현한 코드는 여기서 확인할 수 있다.
1. 요청 값이 유효하지 않은 경우
요구사항에는 '할 일' 에 몇 글자를 적을 수 있게 혹은 '작성자 이름' 은 몇 글자까지 입력 받을 수 있도록 같은 내용이 명시 되어있지 않다. 하지만 나의 경우 테이블 생성시 적절한 크기를 할당하고자 'text' 타입이 아닌 'varChar' 타입을 사용해 컬럼을 생성했다. 'varChar' 타입을 사용하다보니 자연스레 '최대 크기' 에 대한 값을 지정해야 했다. '최대 크기' 를 지정했기에 사용자가 이 '최대 크기' 보다 긴 데이터를 입력하게 되면 해당 데이터를 DB 에 저장할 때 문제가 발생할 것이다.
바로 위와 같은 요청에서 말이다. 현재 'schedule' 테이블의 'body' 컬럼은 'varChar(150)', 'author' 컬럼은 'varChar(20)', 'password' 컬럼은 'varChar(6)' 으로 설정해 생성한 상태이다.
위의 API 테스트에서는 'author' 컬럼의 '최대 글자 수(20)' 를 넘는 문자열 데이터를 요청 값으로 전달했다. 그래서 'schedule' 테이블의 'author' 컬럼에 해당 값을 저장할 수 없기에 문제가 발생한 것이다. IntelliJ 에서는 아래와 같은 에러 메시지를 확인할 수 있다.
// 데이터 짤림 : 행 1 의 'author' 열에 대한 데이터가 너무 깁니다.
MysqlDataTruncation: Data truncation: Data too long for column 'author' at row 1
에러메시지 또한 요청 값(객체)의 'author' 의 길이가 너무 길다고 친절히 알려주고 있다.
또한 'schedule' 테이블의 각 컬럼들은 'null' 값을 허용하지 않도록 설정해두었기에 요청 값으로 'null' 을 전달받은 경우에도 아래와 같이 에러가 발생한다.
'body', 'password' 컬럼에는 유효한 값을 전달 받았지만 'author' 에는 요청 값이 없어 'null' 을 전달 받아 위와 같은 에러를 확인할 수 있다.
// 'author' 컬럼은 null 이 허용되지 않습니다.
SQLIntegrityConstraintViolationException: Column 'author' cannot be null
에러메시지 또한 친절하게 'author' 컬럼은 'null' 이 허용되지 않음을 알려주고 있다.
2. 요청 값 검증 및 예외 처리
그래서 현재 필요한 것은 전달받은 '요청 값(객체)' 에 대한 '검증기' 와 검증 시 유효하지 않을 때 발생시킬 '예외' 그리고 그 예외를 처리할 '예외 처리기' 이다.
먼저 요청 값 때문에 예외가 발생하는 기능은 '일정 생성', '일정 수정', '모든 일정 조회' 라고 예상하였다. 먼저 요청 값을 검증하는 역할을 가진 'ScheduleValidator' 인터페이스와 해당 인터페이스를 구현한 'ScheduleValidatorImpl' 클래스 를 아래와 같이 생성했다.
이제 'ScheduleValidator' 가 요청시 전달 받은 요청 값들을 검증할 것이다. 상세한 구현내용은 맨 위에 걸어둔 링크를 통해 확인하길 바란다.
그럼 이렇게 생성한 'ScheduleValidator' 는 어디서 사용될까? 나의 경우 비즈니스 로직이 있는 'ScheduleService' 에서 사용하기로 결정해 아래와 같이 'ScheduleServiceImpl' 에 의존 관계를 추가 하였다.
자 이제 '일정 생성', '일정 수정', '모든 일정 조회' 에 대한 기능을 수행하는 비즈니스 로직들이 'ScheduleValidator' 를 활용할 수 있으므로 요청에 대한 기능을 하기 전, 검증을 수행할 수 있다.
3. 예외 클래스 추가 및 예외 처리
이제 검증을 통해 유효하지 않은 요청 값이라 판단되면 발생시킬 '예외' 가 필요하고 발생시킨 예외를 처리할 '예외 처리기' 가 필요하다. 현재 검증 대상들은 '요청 데이터(값)' 이기에 'NotValidRequestDataException' 예외 클래스를 아래와 같이 생성했다.
'요청 값 검증' 은 컴파일 단계에서 확인할 수 가 없다. 애플리케이션이 실행되고 전달받는 요청에 따라 검증이 이루어지기 때문에 'NotValidRequestDataException' 의 경우 'RuntimeException' 을 상속하도록 하였다.
위의 이미지의 클래스 필드를 보면 'ExceptionCode exceptionCode' 가 존재하는데 'ExceptionCode' 는 클라이언트에게 전달할 '예외 정보' 를 다룰 목적으로 생성한 'enum 클래스' 이다. 해당 클래스는 아래와 같이 작성했다.
'ExceptionCode' 의 각 상수들은 'HttpStatus', '예외 메시지' 정보를 갖는다. 해당 정보는 다음 이야기할 '예외 처리기' 에서 사용된다.
여기까지 내용을 정리하면 "신규 생성한 'NotValidRequestDataException' 은 '유효하지 않은 필드(들)의 이름' 을 'fieldName' 에, 예외로 인한 'HttpStatus 및 예외 메시지' 정보를 'exceptionCode' 에 가지게 된다" 라고 말할 수 있다.
마지막으로 '예외 처리' 에 대한 부분은 이전 Java 개인과제 처럼 try-catch 문을 사용할까도 생각했지만 이왕 Spring 을 시작한 만큼 새로운 방식으로 예외를 처리해보고자 아래와 같은 '예외 처리기' 역할의 'GlobalExceptionHandler' 클래스를 생성하였다.
해당 클래스는 프로젝트에서 발생하는 모든 예외를 처리한다는 의미를 담아 위와 같은 네이밍을 해주었다. 그래서 패키지 내 클래스 위치도 아래와 같다.
4. API 테스트
4-1. 일정 생성
일정 생성시 요청 값 중 '최대 길이' 를 넘는 요청 값이 존재하거나 'null' 인 요청 값이 존재하면 위 이미지들 처럼 예외 정보를 반환하고 HttpStatus 는 '400 Bad Request' 로 출력 된다. 이미지에는 하나의 요청 값으로 예외를 발생시켜 결과를 반환 받았지만 실제 테스트에서는 여러 요청 값이 유효하지 않을 경우 해당하는 요청 값을 모두 예외 정보에 표기해준다.
4-2. 모든 일정 조회
'모든 일정 조회' 의 경우 전달 받는 '검색 조건' 에 대한 API 테스트를 진행했다. 'updateAt(수정일)' 의 경우 'YYYY-MM-DD' 형식이어야 하기에 해당 형식을 지키지 못한 요청 값의 경우 에러 정보를 반환 받게 된다. 그리고 '일정 생성' 과 마찬가지로 'author' 도 '최대 길이' 보다 길다면 에러 정보를 반환 받게 된다. 그리고 두 경우 모두 HttpStatus 는 '400 Bad Request' 로 출력 된다.
특이 사항은 '모든 일정 조회' 의 경우 null 값을 허용하도록 하였다. 조건이 존재하지 않는 경우에도 모든 일정을 조회해야 하기 때문이다. 만약 null 값을 아예 배제하고 싶다면 모든 조건에 기본 값을 가지게 하고 조건에 대한 요청 값이 없을 경우 기본 값으로 모든 일정을 조회하게 해야할 것이다.
4-3. 일정 수정
'일정 생성' API 테스트와 테스트 방식, 결과가 같다. 단, 검증하는 요청 값이 'body', 'author' 뿐이다. 'password' 의 경우 어처피 DB 에서 데이터 조회시 사용되는 Query 의 조건문을 통해 검증이 되기에 따로 '일정 수정' 검증에는 포함시키지 않았다. '일정 생성' API 테스트랑 다르게 모든 요청 값을 null 로 전달하니 'body', 'author' 모두 예외 정보에 표기되는 것을 확인할 수 있다.
'내일배움캠프' 카테고리의 다른 글
[내일배움캠프] TIL - 24.10.15(화) (0) | 2024.10.15 |
---|---|
[내일배움캠프] TIL - 24.10.07(월) (0) | 2024.10.07 |
[내일배움캠프] TIL - 24.09.30(월) (0) | 2024.09.30 |
[내일배움캠프] TIL - 24.09.27(금) (0) | 2024.09.27 |
[내일배움캠프] 일정 관리 앱 - DB 연동 및 API 테스트 (0) | 2024.09.27 |