DTO(Data Transfer Object)

 

 

 

➤ DTO(데이터 전송 객체)란?

 

  • 마틴 파울러(Martin Fowler)의 저서 ‘Patterns of Enterprise Application Architecture’에서 소개되었다.
  • enterprise application architecture의 한 패턴이다.
  • 계층 간 데이터 교환을 위한 자바 bean을 말한다.

 

 

 

➤ DTO는 왜 나온 것인가?

 

실제로 서비스를 만들다보면 실무에서 Request Param에 많은 양의 정보들을 보낸다.

그렇게 되면 @RequestParam의 개수가 계속 늘어나서 코드가 길어지고 보기 어렵다.

요청 데이터로 받을 정보들을 하나의 객체로 전달한다면 훨씬 코드가 간결해 질 것이다.

바로 DTO가 그런 역할을 해준다.

DTO 클래스가 요청 데이터를 하나의 객체로 전달 받는 역할을 해준다.

 

DTO를 사용하면 @RequestParam 부분이 사라지고 Dto 객체로 대체된다.

 

 

 

 

➤ 데이터 유효성(Validation) 검증의 단순화

 

클라이언트 쪽에서 올바르지 않은 데이터 형식으로 요청할 수 있다.

예를 들면 휴대폰 번호에 문자를 넣거나, 이메일에 @를 안 쓴다거나 이름에 이모티콘을 넣는 등 클라이언트가 우리가 기대하지 않은 값을 전달할 수도 있다.

이럴 때 데이터 유효성을 검사하지 않으면 틀린 형식도 정상적으로 핸들러 메서드에 전달받을 수 있다.

 

서버에서 유효한 데이터를 전달받기 위해 데이터를 검증하는 것을 유효성(Validation) 검증이라고 한다.

 

if문을 이용해서 직접 데이터가 맞는 형식인지 확인해서 틀리면 요청을 거부하도록 작성할 수 있다.

하지만 이 방법은 형식별로 코드가 다르고 복잡하다.

 

HTTP 요청을 전달 받는 핸들러 메서드는 요청을 전달 받는 것이 주 목적이기 때문에 최대한 간결하게 작성되는 것이 좋다.

 

 

 

➤ DTO 클래스 만들기

 

DTO는 타입을 지정할 변수와 getter/setter, 애너테이션으로 구성되어 있다.

DTO 클래스를 사용하면 유효성 검증 로직을 DTO 클래스로 빼내어 핸들러 메서드의 간결함을 유지할 수있다.

 

 

 

 

❑ DTO 유효성 검증

 

핸들러 메서드의 매개변수 중 유효성 검증을 원하는 부분에 작성한 Dto 객체로 매개변수를 작성하고 @Valid 를 타입 앞에 써준다.

@PostMapping
public ResponseEntity postMember(@Valid MemberDto memberDto) {
	...
}

 

@Valid 는 ~Dto 객체에 유효성 검증을 적용하게 해준다.

DTO 유효성 검증의 사용 목적 : 비용이 많이 드는 작업인 HTTP 요청의 수를 줄이기 위함 + 도메인 객체와의 분리

 

 

 

 

 

 

➤ HTTP Request Body가 JSON 형식일 경우

 

 

요청 데이터 🟰 Request Body

 

~PostDto, ~PatchDto 등의 이름으로 dto 클래스 생성

사용하려는 http 메서드에 따라 다르게 명명하면 된다.

 

 

▶️ @RequestBody

 

JSON 형식의 Request Body를 Dto 클래스의 객체로 변환 시켜주는 역할을 한다.

클라이언트에서 전송하는 Request body가 JSON 형식이어야 한다.

JSON 형식이 아닌 다른 형식의 데이터 전송할 경우 Spring 내부에서 ‘Unsupported Media Type’ 과 같은 에러 메시지를 포함한 응답을 전달한다.

 

 

▶️ @ResponseBody

 

JSON 형식의 Response Body를 클라이언트에 전달하기 위해 DTO 클래스의 객체를 Response Body로 변환하는 역할을 한다.

Spring MVC에서 핸들러 메서드에 @ResponseBody 애너테이션이 붙거나 핸들러 메서드의 리턴값이 ResponseEntity 일 경우 내부적으로 HttpMessageConverter 가 동작하여 응답 객체(DTO 클래스의 객체)를 JSON 형식으로 바꿔준다.

 

 

 

➤ JSON Serialization(직렬화) & JSON Deserialization(역직렬화)

 

▶️ Serialization(직렬화)

서버 쪽에서 클라이언트에 응답 데이터로 DTO같은 자바 객체를 JSON형식으로 변환하는 것

Java 객체 ➡️ JSON

 

▶️ Deserialization(역직렬화)

클라이언트에서 JSON 형식의 데이터를 서버에 전송 ➡️ 서버 쪽 애플리케이션에서 전달받은 JSON 형식의 데이터를 DTO 같은 자바 객체로 변환하는 것

JSON ➡️ Java 객체

 

 

 

 

DTO 유효성 검증(Validation)

 

 

➤ DTO 유효성 검증(Validation)이 필요한 이유

 

REST API 통신을 하는 프론트엔드 쪽 웹 앱에서도 자바스크립트를 이용해서 1차적으로 유효성 검사를 진행한다.

그렇다면 왜 굳이 백엔드 애플리케이션에서도 유효성 검증을 할 필요가 있을까?

프론트엔드 쪽에서 유효성 검사를 통과했다고 해서 그 값이 반드시 유효한 값이라는 보장은 없다.

프론트 엔드에서 유효성 검사를 통과한 뒤 HTTP Request 요청이 전송된다.

여기서 자바스크립트로 전송되는 데이터는 개발자 도구를 사용해서 브레이크 포인트(break point)를 건 뒤 얼마든지 그 값을 조작할 수 있기 때문이다.

그렇기에 백엔드 애플리케이션에서도 유효성 검증을 해줄 필요가 있다.

 

 

 

➤ DTO 클래스에 유효성 검증 적용하기

 

유효성 검증을 위한 의존 라이브러리 추가

DTO 클래스에 유효성 검증을 적용하기 위해서 Spring Boot에서 지원하는 Starter가 필요하다.

 

build.gradle 파일의 dependencies 항목에 아래 항목 추가

implementation 'org.springframework.boot:spring-boot-starter-validation'

 

 

 

➤ 유효성 검증에 사용하는 주요 애너테이션

 

▶️ @NotBlank

  • 정보가 비어있지 않은지 검증한다.
  • null 값과 공백(“”), whitspace(“ “) 모두 허용하지 않는다.
  • attribute message로 원하는 에러 메시지를 넣을 수 있다.

 

▶️ @Pattern

  • attribute regexp 로 작성한 정규표현식(Regular Expression)에 매치되는 data인지 검증한다.
  • 유효성 검증에 실패하면 message attribute에 작성한 에러 메시지가 콘솔에 출력된다.

 

 

▶️ @Size(min= , max= )

  • 문자열 또는 배열이 지정된 길이 사이인지 검증한다.

 

▶️ @Max(value) / @Min(value)

  • 값이 value에 적은 값의 이상인지 이하인지 검증한다.

 

▶️ @NotNull

  • null 값이 아닌 경우만 통과한다.

 

▶️ @NotEmpty

  • 공백을 포함해서 길이가 0이면 오류 발생한다.

 

▶️ @Email

  • 유효한 이메일 주소가 포함되어 있지 않을 경우 유효성 검증에 실패한다.

 

 

 

정규식 연습할 수 있는 페이지

(알려주신 페어분께 감사드립니다.ㅎㅎ)

https://regexr.com/

 

RegExr: Learn, Build, & Test RegEx

RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

regexr.com

 

 

 

 

※ CSR(Client Side Rendering) vs SSR(Server Side Rendering)

 

Rendering의 대상은? HTML

 

CSR(Client Side Rendering)

 

SSR(Server Side Rendering)

서버 쪽에서 HTML 렌더링

HTML 페이지를 클라이언트 쪽에 내려준다.

HTML을 템플릿으로 취급, 동적인 데이터를 채워준다.