공통 응답 객체 ApiResponse로 처리하기

Jiwon Jung·2025년 11월 18일

스프링(Spring)

목록 보기
13/20

저번에 공통 응답 객체에 대해 공부 했었는데, 이번 포스팅에서 내용을 다시 정리하려고 한다.


🌱 API 마다 다른 응답 구조를 가진다면?

각 API 마다 다른 응답 구조 가지는 것은 좋지 못하다.

예를 들어, 성공 응답은 그냥 JSON 객체 자체로 응답하고, 실패 응답은 상태 코드만 준다던지 상황에 따라 응답 형태가 제각각이라면 프론트 개발자는 불편을 겪게 된다.

그래서 공통 응답 객체를 사용해서 성공과 실패 케이스 모두 통일된 형식으로 처리하는 것이 좋다.

그에 따라서 원래는 ErrorResponse로 에러만 공통 되게 처리했는데, 오늘 과제를 하면서 성공 요청까지 한 번에 통일되게 처리하는 방향으로 리팩토링 했다.

🌱 응답 구조를 표준화 해야 하는 이유

  • 프론트/앱 개발자와 협업이 쉬워진다.
  • 에러 발생 시 원인 추적 속도와 디버깅 속도가 향상된다.
  • API 명세에서 응답 구조 일관성이 확보된다.
  • 테스트 코드에서 응답 구조 검증이 단순해진다.

🌱 가장 많이 쓰이는 공통 응답 포맷

{
  "success": true,
  "code": "S200",
  "message": "정상 처리되었습니다.",
  "data": {
  	"id": 1,
    "name": "홍길동"
  }
}
{
  "success": false,
  "code": "C100",
  "message": "로그인에 실패하였습니다.",
  "error": {
  	"field": "email",
    "message": "이미 존재하는 이메일입니다."
  }
}
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class ApiResponse<T> {

    private boolean success;
    private String code;
    private String message;
    private T data;

    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<>(true, "S200", "요청이 성공적으로 처리되었습니다.", data);
    }

    public static <T> ApiResponse<T> error(String code, String message, T errorDetail) {
        return new ApiResponse<>(false, code, message, errorDetail);
    }
}

상태 코드 값은 Enum을 이용해서 다뤘다.

@Getter
@AllArgsConstructor
public enum SuccessCode {
    SUCCESS_SIGNUP("S001", "회원가입에 성공했습니다."),
    SUCCESS_LOGIN("S002", "로그인에 성공했습니다."),

    private final String code;
    private final String message;
}
@PostMapping
public ResponseEntity<ApiResponse<SingUpResponse>> signUp(@Valid @RequestBody SignUpRequest request) {
    SingUpResponse result = userService.signUp(request);
    return ResponseEntity.ok(ApiResponse.success(result));
}

0개의 댓글