데이터 삭제 API의 위험성

김건우·약 13시간 전

개발 이야기

목록 보기
17/17
post-thumbnail

시작하기 전에

이는 굉장히 개인적이고 주관적인 '저'만의 생각입니다. 그저 한 명의 개발자가 가지고 있는 생각 중 하나로 봐주시면 감사하겠습니다.


어떤 프로젝트에서 서버를 또는 DB 파트를 맡아서 하다 보면 자연스럽게 데이터를 삭제하는 API를 만들게 된다. 그것이 단순 게시글 삭제던지, 회원 탈퇴던지 말이다.

그냥 뭐 JPA 써서 void deleteById(String userId); 하고 난 다음에 대충 204 띄우면 되는거 아니야?

아니다. 그렇게 간단한 것이었으면 이 글이 쓰이지도 않았을 것이다.

그래서 왜 안됨

우선 가장 먼저 알아야 하는건

이 데이터가 정말 삭제가 되어도 괜찮은가?

그 데이터가 유저 정보가 되었던, 게시글이 되었던. 현재 우리 기능에서 우선 복구 불가능한 삭제가 이루어져도 문제가 없는가? 라는걸 고민해야 한다.

예를 들어서 메일함에 경우 삭제한다고 해도 휴지통에 들어가 있다가 30일 뒤에 삭제가 되고는 한다. 이런 경우에는 데이터가 삭제되면 안되는 것이다.

그렇다면 우리는 이제 겉으로는 삭제 이지만 실제로는 비활성화 상태로 취급하는 방식을 도입해야 한다. 이걸 고급진 언어로 Soft Delete 라고 한다.

좀 더 복잡한 문제들

'이야 그럼 이제 Soft Delete 시키면 전부 다 해결이네?' 라고 생각할 수 있다.

정말 기초적인 단계에 작은 프로젝트라면 그럴 수 있다. 단순 게시판 같은거라면 해봤자 유저 개체 하나, 게시글 하나 정도에서 그칠 것이기에 고려할 것도 많이 없다.

하지만 여기서 만약 좀 더 복잡한 단계의 구조를 가진 프로젝트라면 복잡해진다.

회원탈퇴

여기 만약에 어떤 서비스에서 유저가 가지고 있는 정보가 아래와 같다고 해보자

  1. 유저ID
  2. 이메일, 비밀번호 같은 개인식별정보
  3. 작성한 게시글
  4. 작성한 댓글
  5. 좋아요 목록
  6. 팔로우, 팔로워
  7. 활동 기록
  8. 결제 정보
  9. 결제 기록

만약 여기서 유저가 회원 탈퇴를 하게 되면 아래 모든 정보가 비활성화 상태로 돌아가야 한다. 그럼 이때 고려해야 할 것들이 많아진다.

  • 서로 다른 테이블에 상태 전이는 어떻게 시킬 것인가
  • 보관 기간은 어떻게 되어야 하는가
  • 비활성화 기간 동안 로그인 시도는 어떻게 할 것인가
  • 같은 DB에 두어야 하는가? 아니라면 어디에 두어야 하지?
  • 이 유저를 팔로우 또는 팔로잉하고 있는 다른 활성 유저에게 어떻게 처리해 줘야 하지?

그 외에도 어떤 기능을 추가적으로 제공하느냐에 따라서 고려해야하는 요소들이 더 많아질 것이다.

그럼 어떻게 해야하지

위에 질문들에 대해 정말 많은 답들과 해결법들이 있겠지만 근본적으로 저런 질문들이 무차별적으로 쏟아지는걸 방지하기 위해서는 'Soft Delete의 남발' 부터 멈춰야 한다.

Soft Delete는 어디까지나 '장기적으로 보관이 필요한 데이터, 또는 복구를 필요로 할 가능성이 있는 데이터들'에 한해서만 이루어져야 한다. 일단 모든 곳에 Soft Delete를 적용한다고 다 되는게 아니라는 뜻이다.

위에 회원 정보를 예시로 들어보자. 다른 유저와 상호 작용하지 않는 본인의 게시글이라던가 이메일, 비밀번호 처럼 외부에서 특정 유저를 식별할 수 있는 데이터를 탈퇴 이후에도 계속 가지고 있어야 하는가? 아마 높은 확률로 그렇지 않을 것이다.

유저 개인을 식별하는건 UUID 정도로 충분하며 다른 계정과 상호작용하지 않은 게시글 정도는 바로 삭제되어도 무관할 것이다. A라는 게시글이 지워진다고 해도 다른 유저에게 영향을 주는 것은 거의 없을 것이기 때문이다. 만약 유저가 그때 그 게시글을 다시 찾아가도 그냥 404를 띄우면 그만이다.

다만 댓글과 좋아요에 경우에는 탈퇴한 유저가 다른 유저에게 직접 영향을 주는 데이터이다. 다른 유저 입장에서는 갑자기 자신의 게시글에 댓글과 좋아요가 없어지는 것이기에 섯부른 삭제는 혼동을 불러올 수 있다. 팔로우, 팔로잉도 같은 이유이다.

마지막으로 결제 정보는 특히나 더 예민하다. 탈퇴를 한 시점에서 혹시 모를 환불 요청을 위해 결제를 했다는 기록 자체는 남겨둬야 하나 결제 수단, 빌링키 등 예민한 정보까지 저장하고 있을 필요는 없는 것이다.

이렇듯 데이터에 대해 무작정 일단 보관하고 본다 라는 방향 보다는 '데이터의 목적과 타당성'을 가지고 보관의 유무를, 즉 Soft Delete 적용의 유무를 정하는 것을 지향해야 한다.

그럼 데이터만 잘 구분 하면 되는건가?

반은 맞는 말이다. 위에서 말한대로 데이터의 목적에 따라서 저장할지, 아예 삭제할지 여부를 잘 정하기만 해도 사실 잘 짜여진 삭제 API 라고 볼 수 있다.

다만 그렇게 되었을 때 우리는 항상 '상태 전이' 에 대해서 고민을 해야한다.

일단 상태 자체도 구분이 되어야 한다. 일반 활성 유저, 비활성화 유저 부터 시작해서 각 활성화 된 유저와 비활성 유저가 가지는 데이터들에서의 상태들. 조회할 때 비활성 유저일 경우 어떤 상태 전이 로직을 거쳐서 어떤 상태 코드를 반환해야 할지 등등.

고려할게 정말 많다.

삭제라는 것은 다른 API와 로직에도 영향을 주는 큰 API이다. 상태가 변하는 것이기 때문이다. 그렇기에 이 상태를 잘 관리하는 것 또한 삭제 API를 더 잘 설계하는 방법이다.

결론

항상 데이터를 다루면서 우리는 근본적으로 이 데이터가 무엇을 의미하고 어떤 목적을 가지고 우리가 저장하고 사용하는지를 인지를 해야한다. 그렇게 해야지만 더 좋은 품질의 서비스를 사용자에게 제공하고 또 기능들을 개선해 나갈 수 있을 것이다.

무지성 AI 딸깍이 점점 유행이 되어가는 지금 이 시대에, 당신의 삭제 API는 안녕한지 한 번 더 고민해 봐야 할 듯 하다.

profile
백엔드 개발자, 김건우입니다.

0개의 댓글