단 1개의 프로필 이미지를 등록하는 기능을 새로 만들어야 했다.
단순하게 새 이미지 넣고, 기존에 있던 이미지 지우기만 하면 될 거라고 생각했다.
실제로 구현하다보니 간단하지 않아서 기록을 남겨야 겠다고 생각했다.
편의상 user 테이블에 image 컬럼에 이미지경로를 저장한다고 하자.
(user.image)
AWS S3에 실제 이미지를 저장하고 그 경로를 DB에 저장한다.
수도코드
문제점
사진이 바뀌지 않은 경우, 같은 경로로 요청을 할 수 있다.
수도코드에 따라 기존 이미지를 지운 후, 그 지운 경로에 있는 이미지를 저장하려 하면..
그 이미지는 이미 없다. 😇
이미지 등록 버튼을 누를 때, 새 이미지를 등록한 경우에만 api 호출을 해달라고 프론트단에 얘기할 수도 있지만, 어쨌든 api 에 허점이 있다는 게 싫었다.
모든 에러사항을 차단하려는 개발자.. 그것이 나다. 😎
모든 경우의 수를 정리해 봤다.
최초로 프로필 사진을 등록함.
프로필 사진을 다른 사진으로 교체함.
프로필 사진을 지움.
프로필 사진 교체없이 이미지 등록 api 호출.
각각의 경우에 어떻게 처리할 지 정리해봈다.
경우에 따른 처리
소스
// DB에 경로가 저장되어있고, 그 경로와 새로 등록하려는 경로가 다른경우
if (user.image && (user.image !== request.input('image'))) {
// 기존 이미지를 지운다.
await S3Utilities.deleteImage(user.image)
}
// 1. 새로 등록하려는 경로에 데이터가 있고, DB에 있는 경로와 새 경로가 다른 경우
// 새 이미지 저장 후 경로를 DB에 저장
// 2. 새로 등록하려는 경로가 null로 들어오면, null을 DB에 넣는다.
// 3. 새로 등록하려는 경로와 DB경로가 같으면, 같은 경로를 DB에 넣는다.
user.image = request.input('image') && (user.image !== request.input('image'))
? await S3Utilities.postImage(request.input('image')) : request.input('image')
혹시 더 좋은 방법이 있으면 댓글로 알려주세요. 😉