[스프링부트 #20] REST API 설계의 핵심

도경원's avatar
Aug 25, 2025
[스프링부트 #20] REST API 설계의 핵심

1. DTO와 엔티티는 분리해야한다.

@RequestBody : JSON 데이터를 자바 객체로 변환해 받는다. insert, update 시에는 해당 행을 리턴받아 DTO로 변환해 응답하는 것이 좋다. DTO는 Entity를 받아 생성자에서 필요한 데이터만 추출한다.
민감 정보(예: 비밀번호)는 반드시 제외한다.
@Data public class UserDTO { private Integer id; private String username; private String email; public UserDTO(User user) { this.id = user.getId(); this.username = user.getUsername(); this.email = user.getEmail(); } }
엔티티를 그대로 응답하면 양방향 매핑 때문에 JSON 직렬화 시 무한 참조 문제가 발생할 수 있으므로 반드시 DTO로 변환한다.

2. 객체지향 원칙 - 상태 변경은 행위를 통해

상태(필드)는 private로 두고, 메서드를 통해서만 변경해야 한다. 여러 객체가 상태를 가질 경우 메서드 호출로 통신해야 한다. 유지보수 시 의존성을 줄이기 위해 화면별로 필요한 필드만 갖춘 DTO를 정확히 설계해야 한다.

3. 예외 처리 - GlobalExceptionHandler

API 에러 응답은 하나의 통일된 DTO 포맷으로 내려준다. HTTP 상태코드와 메시지를 함께 반환한다.
ResponseEntity를 사용해 바디와 상태코드를 명시적으로 작성한다.
나는 200, 400, 401, 403, 404, 500 등 주요 상태코드별 커스텀 예위 클래스를 설계하였다.
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception400.class) public ResponseEntity badRequest(Exception400 e) { return new ResponseEntity(Resp.fail(400, e.getMessage()), HttpStatus.BAD_REQUEST); } @ExceptionHandler(Exception401.class) public ResponseEntity unAuthorized(Exception401 e) { return new ResponseEntity(Resp.fail(401, e.getMessage()), HttpStatus.UNAUTHORIZED); } @ExceptionHandler(Exception403.class) public ResponseEntity forbidden(Exception403 e) { return new ResponseEntity(Resp.fail(403, e.getMessage()), HttpStatus.FORBIDDEN); } @ExceptionHandler(Exception404.class) public ResponseEntity notFound(Exception404 e) { return new ResponseEntity(Resp.fail(404, e.getMessage()), HttpStatus.NOT_FOUND); } @ExceptionHandler(Exception500.class) public ResponseEntity serverError(Exception500 e) { return new ResponseEntity(Resp.fail(500, e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(Exception.class) public ResponseEntity unknown(Exception e) { System.out.println("로그 기록: " + e.getMessage()); return new ResponseEntity(Resp.fail(500, "관리자에게 문의하세요"), HttpStatus.INTERNAL_SERVER_ERROR); } }

4. REST API 설계 포인트

  • URL은 자원 중심 (/api/boards/5) → 복수형 사용 권장한다.
  • Content-Type에서 MimeType 지정 중요 → application/json
  • REST API는 프로토콜(규칙)이며, 약속을 팀 내에서 합의하고 일관성 있게 적용한다.
  • 처음에는 DTO를 넉넉히 만들고 필요 데이터만 꺼내 쓰는 방식도 괜찮지만, 유지보수성을 위해 정확한 DTO 설계가 필수이다.
 

요약

  1. DTO는 엔티티와 분리하고, 민감정보는 제외하고,
  1. 상태 변경은 반드시 메서드를 통해서 한다.
  1. 에러 응답 포맷과 상태코드 표준화한다.
  1. REST API URL과 응답 구조 일관성 유지해야 한다.
  1. JSON 직렬화 시 무한 참조 방지를 위해 엔티티 직접 반환 지양하고, DTO 사용한다.
 
Share article

Gyeongwon's blog