이 글에서는 스프링 부트 애플리케이션에서 API 설계 시 Entity 클래스를 반환하는 것이 바람직하지 않은 이유와 해결 방법에 대해 알아보겠습니다.
먼저 간단한 예시 코드를 통해 Entity 클래스를 반환하는 API를 살펴봅시다.
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("User not found"));
}
}
이 API는 GET /api/users/{id}
요청을 통해 사용자 ID에 해당하는 User
Entity 객체를 직접 반환합니다.
데이터 노출 위험
Entity 클래스에는 불필요한 필드(예: 암호화된 비밀번호)가 포함될 수 있으므로, 민감한 데이터가 노출될 수 있습니다.
순환 참조 문제
Entity 클래스 간에 양방향 관계가 있는 경우, 직렬화 과정에서 무한 루프에 빠질 수 있습니다.
과도한 데이터 로딩
Entity 클래스에 연관 관계가 있는 경우, 필요 이상의 데이터가 로딩되어 성능 저하가 발생할 수 있습니다.
레이어 분리 위배
Entity 클래스는 영속성 레이어(Persistence Layer)에 속하므로, 프레젠테이션 레이어(Presentation Layer)에서 직접 사용하는 것은 레이어 분리 원칙에 위배됩니다.
Entity 클래스 대신 DTO(Data Transfer Object) 또는 VO(Value Object)를 사용하여 필요한 데이터만 반환하는 것이 좋습니다. 예를 들어:
// UserDto.java
public class UserDto {
private Long id;
private String username;
private String email;
// getters, setters
}
// UserController.java
@GetMapping("/{id}")
public UserDto getUserById(@PathVariable Long id) {
User user = userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("User not found"));
return modelMapper.map(user, UserDto.class);
}
이렇게 DTO를 사용하면 다음과 같은 이점이 있습니다:
결론적으로, API 설계 시 Entity 클래스를 직접 반환하는 대신 DTO나 VO를 사용하는 것이 권장됩니다. 이를 통해 보안, 성능, 유지보수성 등의 측면에서 이점을 얻을 수 있습니다.