-
Spring Boot 시리즈 5편 – API 응답 구조 표준화 전략: 일관된 성공/실패 응답 설계하기기술과 산업/언어 및 프레임워크 2025. 4. 17. 20:15728x90
Spring Boot에서 API 응답 형식을 일관되게 유지하는 방법을 소개합니다. ApiResponse, ApiError 구조 설계로 성공과 실패 응답을 표준화합니다.
Spring Boot 시리즈 5편 – API 응답 구조 표준화 전략: 일관된 성공/실패 응답 설계하기
REST API를 설계하면서 많은 개발자가 놓치는 부분 중 하나가 응답 구조의 통일성입니다.
이번 편에서는 실무에서 바로 적용할 수 있는 성공/실패 응답 구조의 표준화 방식,
그리고 API 일관성을 높이는 설계 전략을 소개합니다.
🔍 왜 응답 구조를 통일해야 할까?
- 프론트엔드 개발자와의 협업 시 가독성과 처리 효율 증가
- 에러 처리 및 디버깅의 일관성 확보
- 테스트 코드 작성 및 API 문서화(예: Swagger)에서 이점
- 기업 API 스타일 가이드라인에도 필수 요소
📦 1. 기본 응답 형식 정의 – ApiResponse
✅ 공통 응답 포맷 설계 예시
{ "success": true, "code": 200, "message": "요청이 성공적으로 처리되었습니다.", "data": { "name": "홍길동", "email": "hong@test.com" } }
✅ 공통 응답 객체 클래스
@Getter @AllArgsConstructor @NoArgsConstructor public class ApiResponse<T> { private boolean success; private int code; private String message; private T data; public static <T> ApiResponse<T> success(T data) { return new ApiResponse<>(true, 200, "성공", data); } public static <T> ApiResponse<T> error(int code, String message) { return new ApiResponse<>(false, code, message, null); } }
❌ 2. 실패 응답 구조 – ApiError
@Getter @AllArgsConstructor public class ApiError { private String field; private String message; }
검증 실패 시 예외 핸들러에서 해당 구조로 리턴할 수 있습니다:
List<ApiError> errors = ex.getBindingResult().getFieldErrors().stream() .map(err -> new ApiError(err.getField(), err.getDefaultMessage())) .collect(Collectors.toList()); return ResponseEntity.badRequest().body(ApiResponse.error(400, "입력값 오류").withErrors(errors));
🧠 3. Controller에서의 적용 예시
@PostMapping public ResponseEntity<ApiResponse<UserDto>> createUser(@Valid @RequestBody UserDto dto) { UserDto saved = userService.createUser(dto); return ResponseEntity.ok(ApiResponse.success(saved)); }
모든 컨트롤러 응답을 ApiResponse<T>로 통일하면, 클라이언트는 항상 동일한 구조로 데이터를 파싱할 수 있습니다.
⚙️ 4. 글로벌 예외 처리에서의 활용
@ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<ApiResponse<List<ApiError>>> handleValidationError(MethodArgumentNotValidException ex) { List<ApiError> errors = ex.getBindingResult().getFieldErrors().stream() .map(err -> new ApiError(err.getField(), err.getDefaultMessage())) .collect(Collectors.toList()); return ResponseEntity.badRequest().body(ApiResponse.error(400, "유효성 검사 실패", errors)); }
🧱 5. 상태코드와 메시지 관리 전략
✅ 상태 코드/메시지를 상수화
public class ApiCode { public static final int OK = 200; public static final int VALIDATION_ERROR = 400; public static final int INTERNAL_ERROR = 500; }
또는 Enum으로 관리해도 좋습니다:
@Getter @AllArgsConstructor public enum ApiStatus { OK(200, "성공"), VALIDATION_ERROR(400, "유효성 오류"), SERVER_ERROR(500, "서버 오류"); private final int code; private final String message; }
✅ 마무리 요약
항목 내용
응답 포맷 success, code, message, data 필드로 통일 에러 구조 ApiError 리스트로 필드별 메시지 제공 적용 위치 Controller, ExceptionHandler 전면 적용 확장성 Enum/상수 기반 상태코드, 메시지 관리 가능 장점 협업, 유지보수, API 문서화(예: Swagger)에서 강력한 일관성 확보
📌 다음 편 예고
Spring Boot 시리즈 6편: Swagger를 활용한 API 문서 자동화 전략 – 실무 적용 가이드
728x90'기술과 산업 > 언어 및 프레임워크' 카테고리의 다른 글
Spring Boot 고급 시리즈 2편 – 유지보수 가능한 서비스 아키텍처 설계 전략 (0) 2025.04.18 Spring Boot 고급 시리즈 1편 – @Transactional 완전 정복: 실무 트랜잭션 설계 전략 (0) 2025.04.17 Spring Boot 시리즈 4편 – @Valid 입력값 검증과 글로벌 예외 처리 전략 (0) 2025.04.17 Spring Boot 시리즈 3편 – JPA로 DB 연동하기: Entity와 Repository 설계 전략 (0) 2025.04.16 Spring Boot 시리즈 2편 – REST API 설계와 Controller 작성 가이드 (1) 2025.04.15