프로필 업데이트 API를 고도화를 하다보니
테스트를 하면서 생긴 문제가 있었다.
이 코드의 흐름을 봐보자.
앞단에서 일정 부분 validation을 먼저 하고 있긴 하다.
그러고 나서 S3에 사진을 올리고, DB에 사진을 저장한다.
문제는 S3와 관련된 Validation을 제외하면 대부분의 Validation이 DB 저장 과정에서 발생한다는 것이다.
현재 도메인 내부에서 Validation을 하는 코드들을 작성했는데
이 코드들은 어쨌든 흐름상
S3에 사진을 저장하고나서 DB에 저장할 때 Validation을 진행하는 구조다.
Validation을 하는 목적이 뭘까?
간단하게 생각하면 도메인 비즈니스 규칙에 맞지 않은 HTTP 요청을 다 걸러내기 위해서다.
가령, Plaything 도메인 규칙에는 아래와 같은 것이 있다.
"프로필 사진을 세장만 업로드 할 수 있고, 이 중에는 메인 사진이 하나 있어야 한다"
프로필 사진이 이미 두장 있는데, 두장을 추가로 업로드 하려고 하거나
사진이 세장이 있는데 사진을 추가로 업로드하려고 할 수 있다.
혹은 사진 업데이트를 하면서 메인 사진을 없애고 새로운 메인 사진을 추가 안할 수도 있다.
이러한 비정상적인 흐름이 DB에 저장되지 않도록 예외를 던지는 것이 Validation이다.
그렇다면, 지금 코드는 왜 문제일까?
S3 작업이 이뤄진 후에 Validation을 한다는 것이 문제다.
예외가 터지면 롤백이 발생한다. 그러면 이전까지의 내용은 DB에 반영되지 않는다.
하지만, S3는 롤백이 되지 않는다. 트랜잭션 롤백은 DB에만 적용되는 것이지 외부 리소스까지 알아서 롤백해주는 개념이 아니다.
그러므로 내가 직접 롤백을 진행한다.
여길 보면 Try catch로 예외를 잡고, S3 롤백을 하는 코드가 있다.
지금까지 내용을 정리해보면 Validation이 비효율적인 이유는
S3 리소스를 이미 쓴 상태에서, 롤백이 되면 S3 자원까지 내가 직접 정리를 해줘야 한다는 것이다.
생각해보면, 도메인 규칙과 맞지 않는 이미지 업데이트 요청은 굉장히 많이 들어올 것이다.
그때마다 S3에 사진을 업로드하고 삭제하는 과정을 반복하는 건 상당한 리소스 낭비다.
이러한 비효율성이 발생하지 않으려면 Validation을 S3 사용 전에 해주는 게 좋을 것으로 보인다.
Validation은 트랜잭션 롤백에 포함될 필요도 없으니 트랜잭션 범위가 아닌 앞 단에 넣어도 무관하다.
update에서 Validation하는 로직을 다 빼서 validateUpdateRequest 메서드를 만들었다.
그리고 이제 S3 리소스를 사용하기 전에 Validation을 한다.