Java API에서 return 값의 형태 선택(DTO, Map, ResponseEntity)
java api를 만들 때 return 값으로 보통 뭐에 담아줘야 할까?
각각 MODEL 그대로?
아니면 MAP형태로 하는 게 좋을까?
Spring Boot에서 API를 만들 때 클라이언트에게 데이터를 어떻게 반환할지 결정해야 한다.
주로 사용되는 방법은 DTO 객체, Map, ResponseEntity 등이다.
각 방법의 장점과 단점, 그리고 언제 사용하는 게 좋은지 정리해 보자.
1. DTO (Data Transfer Object) 사용 - 가장 일반적인 방법
추천 상황:
반환할 데이터가 고정된 형태이고, 필드(속성)도 정해져 있을 때
직렬화(Json 변환) & 유지보수에 유리
예제 - DTO 사용
@Getter
@Setter
@AllArgsConstructor
public class ItemDto {
private int id;
private String name;
private int price;
}
@RestController
@RequestMapping("/api/items")
public class ItemController {
@GetMapping("/{id}")
public ItemDto getItem(@PathVariable int id) {
return new ItemDto(id, "Laptop", 1500);
}
}
응답 예시 (JSON)
{
"id": 1,
"name": "Laptop",
"price": 1500
}
장점
데이터 구조가 명확해서 유지보수 쉬움
Spring Boot에서 JSON으로 변환 (@RestController의 자동 변환 기능 활용)
IDE에서 필드 자동 완성 지원
단점
DTO가 많아지면 클래스가 많아져 관리가 어려울 수도 있음
2. Map<String, Object> 사용 - 유연한 데이터 반환
추천 상황:
동적으로 데이터 형태가 바뀔 가능성이 있을 때
빠르게 개발해야 할 때 (간단한 API용)
단순한 Key-Value 응답을 줄 때
예제 - Map<String, Object> 사용
@RestController
@RequestMapping("/api/items")
public class ItemController {
@GetMapping("/{id}")
public Map<String, Object> getItem(@PathVariable int id) {
Map<String, Object> response = new HashMap<>();
response.put("id", id);
response.put("name", "Laptop");
response.put("price", 1500);
return response;
}
}
응답 예시 (JSON)
{
"id": 1,
"name": "Laptop",
"price": 1500
}
장점
DTO 클래스를 만들 필요가 없어서 빠르게 개발 가능
유연하게 데이터를 추가/삭제할 수 있음
단점
Map 사용 시, IDE 자동 완성이 어렵고 필드가 정해져 있지 않아서 유지보수 불편
JSON 직렬화 시, 불필요한 타입 변환이 발생할 수도 있음
3. ResponseEntity<T> 사용 - HTTP 상태 코드 포함
추천 상황:
HTTP 응답 상태 코드 (200, 400, 500 등)를 명확하게 반환하고 싶을 때
에러 메시지와 데이터를 함께 보내고 싶을 때
예제 - ResponseEntity<ItemDto> 사용
@RestController
@RequestMapping("/api/items")
public class ItemController {
@GetMapping("/{id}")
public ResponseEntity<ItemDto> getItem(@PathVariable int id) {
ItemDto item = new ItemDto(id, "Laptop", 1500);
return ResponseEntity.ok(item); // 200 OK
}
}
응답 예시 (JSON)
{
"id": 1,
"name": "Laptop",
"price": 1500
}
에러 응답을 보낼 수도 있음
@GetMapping("/{id}")
public ResponseEntity<Object> getItem(@PathVariable int id) {
if (id <= 0) {
Map<String, String> error = new HashMap<>();
error.put("error", "Invalid ID");
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); // 400 Bad Request
}
ItemDto item = new ItemDto(id, "Laptop", 1500);
return ResponseEntity.ok(item);
}
에러 응답 예시
{
"error": "Invalid ID"
}
장점
HTTP 상태 코드와 함께 응답 가능 (200, 400, 500 등)
성공/실패 응답을 명확하게 구분할 수 있음
단점
ResponseEntity<T>를 사용하면 코드가 길어질 수 있음
결론: 언제 어떤 걸 써야 할까?
방법 | 언제 사용하면 좋을까? | 장점 | 단점 |
DTO (객체) | 데이터 구조가 고정적일 때 | 유지보수 용이, 직렬화 쉬움 | 클래스 개수가 많아질 수 있음 |
Map<String, Object> | 빠르게 개발하거나 동적 데이터를 반환할 때 | 유연함, DTO 없이 사용 가능 | 유지보수 어려움 |
ResponseEntity<T> | HTTP 상태 코드 포함한 응답이 필요할 때 | 응답 상태 명확, 성공/실패 구분 가능 | 코드 길어질 수 있음 |
일반적인 경우에는 DTO 사용이 가장 추천됨
빠르게 개발할 때는 Map<String, Object> 사용 가능
에러 처리까지 고려하려면 ResponseEntity<T> 사용
베스트 프랙티스:
- 일반적으로는 DTO 객체 사용
- 동적 데이터가 필요하면 Map 사용
- HTTP 응답 상태 코드가 필요하면 ResponseEntity<T> 사용
그래서 가장 좋은 방법?
- DTO + ResponseEntity<T> 조합
- 일반적인 API에는 DTO 사용
- 예외 처리 시 ResponseEntity<T> 사용
'무한루프 > 개발, 업무' 카테고리의 다른 글
MS-SQL 저장 프로시저(Stored Procedure) 작성 예제 (0) | 2025.03.03 |
---|---|
엑셀 스네이크표기법 -> 카멜표기법 문자열 변환 함수 (0) | 2025.03.01 |
Cannot load driver class: org.mariadb.jdbc.Driver Maria DB 설정 셋팅 에러 (1) | 2025.02.28 |
DTO와 VO의 차이 (0) | 2025.02.28 |
MS-SQL 기본 정보 및 환경 (0) | 2025.02.26 |