Develog
코드스테이츠 42일차 본문
DTO(Data Transfer Object)
- DTO가 무엇인지 이해할 수 있다
- DTO Validation이 무엇인지 이해할 수 있다.
- Controller에 DTO 클래스를 적용할 수 있다.
HTTP 요청/응답에서의 DTO(Data Transfer Object)
DTO(Data Transfer Object)란?
데이터를 전송하기 위한 용도의 객체 정도로만 생각하자
DTO가 필요한 이유?
DTO 클래스를 이용한 코드의 간결성
@RequestParam 애너테이션을 사용하면 정보가 많아질수록 코드가 길어질 수 밖에 없다.
하지만 DTO 클래스를 통해 요청 데이터를 하나의 객체로 전달 받는 역할을 해줄 수 있다.
DTO 클래스를 사용하는 가장 중요한 목적은 비용이 많이 드는 작업인 HTTP 요청의 수를 줄이기 위함이라고도 할 수 있다.
데이터 유효성(Validation) 검증의 단순화
핸들러 메서드는 클라이언트의 요청 데이터에 대한 유효성 검증 작업을 거치지 않는다면 email 주소를 ‘hgd1234@gmail.com’ 같은 이메일 주소 형식이 아닌 ‘hgd1234’ 같은 단순 문자열로 전송해도 정상적으로 핸들러 메서드 쪽에서 전달 받을 수 있을 것이다.
이처럼 서버 쪽에서 유효한 데이터를 전달 받기 위해 데이터를 검증하는 것을 유효성(Validation)검증이라고 한다.
if (!email.matches("^[a-zA-Z0-9_!#$%&'\\*+/=?{|}~^.-]+@[a-zA-Z0-9.-]+$")) {
throw new InvalidParameterException();
}
위와 같이 유효한 이메일 주소인지 확인하기 위한 코드를 작성할 수 있을 것이다.
하지만 다른 항목에도 유효성 검사가 필요하게 되면 핸들러 내의 코드는 유효성을 검증하는 로직들이 넘쳐나고 그만큼 코드의 복잡도도 높아질 것이다.
HTTP 요청을 전달 받는 핸들러 메서드는 요청을 전달 받는 것이 주 목적이기 때문에 최대한 간결하게 작성되는 것이 좋다.
그렇기에 DTO 클래스를 사용하면 유효성 검증 로직을 DTO 클래스로 빼내어 핸들러 메서드의 간결함을 유지할 수 있다.
따로 빼내었던 DTO클래스는
@PostMapping
public ResponseEntity postMember(@Valid MemberDto memberDto) {
return new ResponseEntity<MemberDto>(memberDto, HttpStatus.CREATED);
}
위와 같이 사용할 수 있다.
- postMember() 핸들러 메서드의 파라미터인 MemberDto 앞에 붙은 @Valid 애너테이션은 MemberDto 객체에 유효성 검증을 적용하게 해주는 애너테이션이다.
DTO 클래스를 만들 때, 주의해야 할 부분은 멤버 변수 이외에 각 멤버 변수에 해당하는 getter 메서드가 있어야 한다는 것이다.
getter 메서드가 없으면 Response Body에 해당 멤버 변수의 값이 포함되지 않는 문제가 발생한다.
setter 메서드는 필수 항목은 아니지만 개발자의 필요에 의해서 있을 수도 있고, 없을 수도 있다.
매번 getter/setter 메서드를 작성하는 것은 비효율적일 수 있다.
이런 부분을 해결하기 위해 IntelliJ IDE에서 지원하는 Generate Code 기능이 있으니 참고하도록 하자
Spring MVC에서는 핸들러 메서드에 @ResponseBody 애너테이션이 붙거나 **핸들러 메서드의 리턴 값이 ResponseEntity일 경우, 내부적으로 HttpMessageConverter가 동작하게 되어 응답 객체(여기서는 DTO 클래스의 객체)를 JSON 형식으로 바꿔준다.
클라이언트 쪽에서 JSON 형식의 데이터를 서버 쪽으로 전송하면 서버 쪽의 웹 애플리케이션은 전달 받은 JSON 형식의 데이터를 DTO 같은 Java의 객체로 변환하는데 이를 역직렬화(Deserialization)이라고 한다.
반면에 서버 쪽에서 클라이언트에게 응답 데이터를 전송하기 위해서 DTO 같은 Java의 객체를 JSON 형식으로 변환하는 것을 직렬화(Serialization)라고 한다.
JSON 직렬화(Serialization): Java 객체 → JSON
JSON 역직렬화(Deserialization): JSON → Java 객체
총정리
- DTO는 Data Transfer Object의 약자로 마틴 파울러(Martin Fowler)가 ‘Patterns of Enterprise Application Architecture’ 라는 책에서 처음 소개한 엔터프라이즈 애플리케이션 아키텍처 패턴의 하나이다.
- DTO는 주로 클라이언트에서 서버 쪽으로 전송하는 요청 데이터를 전달 받을 때, 서버에서 클라이언트 쪽으로 전송하는 응답 데이터를 전송하기 위한 용도로 사용된다.
- DTO가 필요한 이유
- 클라이언트의 Request Body를 하나의 객체로 모두 전달 받을 수 있기때문에 코드 자체가 간결해진다.
- Request Body의 데이터 유효성(Validation) 검증이 단순해진다.
- JSON 형식의 Request Body를 전달 받기 위해서는 DTO 객체에 @RequestBody 애너테이션을 붙여야 한다.
- Response Body를 JSON 형식으로 전달하기 위해서는 @ResponseBody 애너테이션을 메서드 앞에 붙여 주어야하지만 ResponseEntity 객체를 리턴 값으로 사용할 경우 @ResponseBody 를 생략할 수 있다.
- 클라이언트 쪽에서 JSON 형식의 데이터를 서버 쪽으로 전송하면 서버 쪽의 웹 애플리케이션은 전달 받은 JSON 형식의 데이터를 DTO 같은 Java의 객체로 변환하는데 이를 역직렬화(Deserialization)이라고 한다.
- 서버 쪽에서 클라이언트에게 응답 데이터를 전송하기 위해서 DTO 같은 Java의 객체를 JSON 형식으로 변환하는 것을 직렬화(Serialization)라고 한다.
Jakarta Bean Validation이란?
우리가 라이브러리처럼 사용할 수 있는 API가 아닌 스펙(사양, Specification) 자체이다.
즉, 이러한 애너테이션들을 이런식으로 구현해서 사용하라는 일종의 기능 명세를 의미한다.
이 Jakarta Bean Validation 스펙을 구현한 구현체가 바로 Hibernate Validator이다.
하지만 Jakarta Bean Validation의 애너테이션을 DTO 클래스에만 사용할 수 있는 것은 아니다.
Java Bean 스펙을 준수하는 Java 클래스라면 Jakarta Bean Validation의 애너테이션을 사용해서 유효성 검증을 할 수 있다라는 사실을 기억하자
Custom Validator를 사용한 유효성 검증
DTO 클래스에 유효성 검증을 적용하다보면 Jakarta Bean Validation에 내장된(Built-in) 애너테이션 중에 우리의 목적에 맞는 애너테이션이 없는 경우가 있을 것이다.
이 경우 우리가 직접 애너테이션을 만들어 사용할 수 있다.
정규 표현식(Regular Expression)은 성능적인 면에서 때로는 비싼 비용을 치뤄야 될 가능성이 있어 모든 로직을 정규표현식 위주로 작성하는 것은 좋은 개발 방식이 아니라고 할 수 있다.
Custom Validator를 구현하기 위한 절차
- Custom Validator를 사용하기 위한 Custom Annotation을 정의한다.
- 정의한 Custom Annotation에 바인딩 되는 Custom Validator를 구현한다.
- 유효성 검증이 필요한 DTO 클래스의 멤버 변수에 Custom Annotation을 추가한다.
기본적으로 CustomValidator를 구현하기 위해서는 ConstraintValidator 인터페이스를 구현해야 한다.
총정리
- 프런트엔드 쪽에서 유효성 검증을 진행했다 하더라도 서버 쪽에서 추가적으로 유효성 검증을 반드시 진행해야 한다.
- 프런트엔드 쪽에서의 유효성 검증 프로세스는 사용자 편의성 측면에서 필요한 작업이다.
- Jakarta Bean Validation의 애너테이션을 이용하면 Controller 로직에서 유효성 검증 로직을 분리할 수 있다.
- Jakarta Bean Validation은 애너테이션 기반 유효성 검증을 위한 표준 스펙이다.
- Hibernate Validator는 Jakarta Bean Validation 스펙을 구현한 구현체이다.
- Spring에서 지원하는 @Validated 애너테이션을 사용하면 쿼리 파라미터(Query Parameter 또는 Query String) 및 @Pathvariable에 대한 유효성 검증을 진행할 수 있다.
- Jakarta Bean Validation에서 빌트인(Built-in)으로 지원하지 않는 애너테이션은 Custom Validator를 통해 Custom Annotation을 구현한 후, 적용할 수 있다.
'코드스테이츠' 카테고리의 다른 글
코드스테이츠 44일차 (0) | 2022.06.28 |
---|---|
코드스테이츠 43일차 (2) | 2022.06.27 |
코드스테이츠 41일차 (0) | 2022.06.23 |
코드스테이츠 40일차 / Section 2 회고 (2) | 2022.06.22 |
코드스테이츠 39일차 (0) | 2022.06.21 |