SpringBoot/REST API 개발

DTO, 응답 포맷 구조화

DEVLIB 2025. 4. 15. 10:15
728x90

1. DTO란?

DTO(Data Transfer Object)란, 데이터 전송을 위한 전용 객체로, 엔티티(Entity)와 분리해서 클라이언트와 통신합니다.

왜 DTO를 써야 하나요?

이유
설명
보안 엔티티 직접 노출 시 DB 필드까지 노출될 수 있음
유연성 API 요청/응답 포맷 변경이 쉬움
계층 분리 Entity ↔ DTO 분리로 테스트 및 유지보수 용이
불필요한 필드 제거 클라이언트가 필요한 정보만 전달 가능

DTO 예시

public class MemberRequestDto {
    @NotBlank
    private String name;
    
    @Email
    private String email;

    private int age;

    // 생성자, getter/setter 생략
}
public class MemberResponseDto {
    private Long id;
    private String name;
    private String email;

    public MemberResponseDto(Member member) {
        this.id = member.getId();
        this.name = member.getName();
        this.email = member.getEmail();
    }
}

2. 응답 포맷 구조화 (API Response Wrapping)

단순히 MemberDto만 응답하는 것이 아니라,
응답에 상태 코드, 메시지, 시간, 데이터 등을 구조화해서 반환하는 것이 실무 표준입니다.

공통 응답 객체 (Generic)

public class ApiResponse<T> {
    private int status;
    private String message;
    private T data;

    public ApiResponse(int status, String message, T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }

    // getter 생략
}

컨트롤러에서 사용 예시

@RestController
@RequiredArgsConstructor
public class MemberController {

    private final MemberService memberService;

    @GetMapping("/api/member/{id}")
    public ResponseEntity<ApiResponse<MemberResponseDto>> getMember(@PathVariable Long id) {
        Member member = memberService.findById(id);
        MemberResponseDto dto = new MemberResponseDto(member);
        return ResponseEntity.ok(new ApiResponse<>(200, "요청 성공", dto));
    }
}

실제 JSON 응답 결과

{
  "status": 200,
  "message": "요청 성공",
  "data": {
    "id": 1,
    "name": "홍길동",
    "email": "test@example.com"
  }
}

 


오류 응답도 통일하면 좋은 구조 예시

{
  "status": 400,
  "message": "이메일 형식이 유효하지 않습니다.",
  "data": null
}

이런 구조로 응답하면, 프론트엔드 개발자도 코드와 메시지를 기반으로 처리 로직을 작성하기 쉬워집니다.


DTO 변환 도우미 라이브러리 

라이브러리
설명
MapStruct DTO ↔ Entity 매핑 자동 생성기
ModelMapper 런타임 기반 매핑, 설정 유연
Lombok DTO에서 boilerplate 줄이기 (@Data, @Builder)

마무리 요약

항목 설명
DTO 요청(Request), 응답(Response)을 위한 전용 클래스
ApiResponse 상태, 메시지, 데이터 구조로 통일된 응답 제공
장점 유지보수, 테스트, 확장성, 명확한 API 문서화 가능
추가 팁 오류 응답도 동일한 포맷으로 관리하면 실무에 유리
LIST