Post

데이터 검증 책임을 어떻게 나눌 것인가

데이터 검증 책임을 어떻게 나눌 것인가

image.png

📌 개요

개인적으로 어떤 기술을 도입하거나 코드를 작성할 때, 개략적으로라도 근거가 있어야 한다고 생각한다. 그렇다고 ‘근거를 먼저 찾고 그 다음 작업을 진행하자!’라는 입장은 아니다. 남들이 닦아 놓은 길을 굳이 외면할 필요는 없다고 생각한다. 실제로 모든 기술 도입이나 코드 작성에 완벽한 근거를 사전에 마련하는 것은 현실적으로 불가능하다. 중요한 것은, 도입 이후에도 꾸준히 근거를 찾아보고, 더 나은 방향이 있다면 유연하게 개선하는 것이 중요하다고 생각한다.

프로젝트를 진행하면서 검증 로직 작성에 대한 이야기가 나왔다. ‘어떤 검증을 어디서 해야 하는가’, ‘중복 검증은 불필요한가, 아니면 방어적 프로그래밍의 일환인가?’와 같은 주제가 논의되었다.

검증 로직에 대해서는 여러 개발자들 사이에서도 의견이 분분하다. 결국, 검증 로직의 위치와 중복에 대한 ‘정답’은 존재하지 않는다. 팀의 합의에 따라 다양한 해석이 가능하며, 도출된 결론이 곧 정답이다. 중요한 것은 팀원들과 충분히 논의하여, 프로젝트에 가장 적합한 기준과 원칙을 세우고, 그 원칙을 따르는 것이다. 작성할 내용 또한 특정 팀 또는 개인의 의견일 뿐이다.

📌 일반적인 데이터 흐름 프로세스

사용자가 보낸 HTTP 요청은 서버로 들어온다. 데이터는 컨트롤러를 통해 서버로 진입한다. 데이터는 컨트롤러를 지나 서비스로 넘어간다. 서비스는 주로 비즈니스 로직이나 DB 조회 등과 같은 작업을 수행한다. CUD 작업을 수행하는 경우 데이터는 엔티티 및 레포지토리까지 전달되어 DB에 반영된다.

📌 그렇다면 중복 검증이란?

특정 필드에 대해 여러 번 검증을 진행하는 것을 중복 검증이라고 볼 수 있을까? 회원가입을 예로 들어 보자. DTO에서 이메일이 null 이 아닌지 검증하고, 서비스 레이어에서 중복 이메일인지 검증한다면, 이는 중복 검증인가? 나는 아니라고 생각한다. 각 레이어의 관심사에 맞는 검증을 진행하기 때문이다. 반면 DTO와 서비스 레이어 모두 null 이 아닌지 검증한다면 이는 중복 검증이라고 볼 수 있겠다.

📌 각 레이어에 어떤 검증을 수행해야 할까?

서비스 레이어에서 null 검증과 중복 이메일 검증 모두 수행하는 것은 어떠한가? 나는 적절한 방법은 아니라고 생각한다. 비즈니스 로직에 집중해야 하는 서비스 레이어에는 그와 관련된 검증만 이루어지는 것이 좋다고 생각한다. 유효성 검증은 컨트롤러와 DTO에서 처리하는 것이 좋다고 생각한다.

즉, 각 레이어가 수행하는 역할에 맞는 검증을 수행하면 된다. 예를 들어 컨트롤러는 데이터가 들어오는 진입점이므로, 값의 유효성을 검증하는 것이 좋을 것이다. 예를 들면 null 여부나 빈 값, 길이, 정규식 등을 검증하는 것이 좋다. 보통 @Valid 어노테이션을 사용하거나 직접 Validator 객체를 만들어 검증한다.

서비스에는 비즈니스 로직 관련 검증을 수행하는 것이 좋다. 예를 들면 이미 가입된 이메일은 회원가입이 불가능하다는 것이 있다. 보통 검증 메서드를 별도로 구현하여 진행한다.

엔티티에서는 보통 도메인 로직과 관련된 검증을 수행하는 것이 좋다. 예를 들면 나이가 음수일 수 없다는 것이 있다. 마찬가지로 검증 메서드를 따로 구현하여 생성자나 팩토리 메서드에서 이를 사용하도록 한다.

도메인에서 수행하는 검증은 객체의 유효성, 일관성에 초점을 맞추고, 비즈니스 검증은 특정 업무 흐름에 초점을 맞춘다.

📌 나의 결론은?

  1. DTO에서는 @Valid 어노테이션으로 검증할 수 있는 부분을 검증한다. 도메인/비즈니스 로직이 변경되어도 변함없는 부분을 검증한다. 단, 절대 변하지 않을 도메인 로직 같은 경우 커스텀 Validator 객체를 통해 검증하는 것을 고려해본다.
  2. 서비스 레이어에서는 비즈니스 로직을 검증한다.
  3. 도메인 레이어에서는 도메인 로직을 검증한다.
This post is licensed under CC BY 4.0 by the author.