[Spring] 공통 응답 정의 및 에러 코드 추가 / 예외 처리

김현진·2023년 5월 22일
0

커플 SNS 프로젝트

목록 보기
1/4

공통 응답

현재 진행 중인 프로젝트에서, API 를 설계할 때 공통 응답 포맷을 어떤 형식으로 할지 프론트엔드 분들과 상의를 한 결과 다음과 같은 포멧으로 응답 형식을 지정했다.

{
	"success" : true,
    "data" : ...,
    "code" : "C001",
    "message" : "..."
}

이와 같이 구성한 이유는 다음과 같다.

  • 성공하였을 경우는 단순히 Http Status Code 로 응답해 주어도 문제가 없지만, 실패했을 경우에는 어떤 이유인지 명확히 알려주어야 했기 때문에
    Http Status Code 만으로는 부족했고, 다음 필드들을 추가했다.
  • message
    • 요청 실패시, 요청 실패에 대한 설명
    • 하지만 해당 필드는 문자열이기 때문에 클라이언트 측에서 예외 처리를 할 때 어려움이 있음
  • code
    • 요청 실패시, 요청 실패에 대한 분류
    • 메시지와 함께 실패 이유르 설명해 줄 수 있고, 클라이언트 측에서 예외 처리 할 때 좀 더 편리하게 사용할 수 있음

구현

공통 응답

  • 응답할 데이터는 다양한 타입이 들어갈 수 있으므로 제네릭으로 선언
  • 성공, 실패시 명확한 이름을 가진 정적 팩토리 메소드로 객체 생성
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class ApiResponse<T> {

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

	public static ApiResponse<Void> ofSuccess() {
		return new ApiResponse<>(true, null, null, null);
	}

	public static <T> ApiResponse<T> ofSuccess(T data) {
		return new ApiResponse<>(true, data, null, null);
	}

	public static ApiResponse<Void> ofFail(ErrorCode errorCode, String message) {
		return new ApiResponse<>(false, null, errorCode.getCode(), message);
	}
}

에러 코드

  • Enum Type 으로 응답시 사용할 Http Status Code 및 Custom Code 작성
  • 내부에 static class 로 예외 메시지 관리
    • 메시지를 한 곳에서 관리하기 위해 이렇게 구성하였으나 한 곳에서만 사용하는 것이 확실하다면 해당 클래스 내부에 선언해도 좋을 것 같다...
@Getter
public enum ErrorCode {

	// CLIENT
	URL_NOT_FOUND(HttpStatus.NOT_FOUND, "C001"),
	METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "C002"),
	METHOD_ARGUMENT_TYPE_MISMATCH(BAD_REQUEST, "C003"),
	MISSING_REQUEST_PARAMETER(BAD_REQUEST, "C004"),
	MEDIA_TYPE_NOT_SUPPORTED(UNSUPPORTED_MEDIA_TYPE, "C005"),

	// SERVER
	SERVER_ERROR(INTERNAL_SERVER_ERROR, "S001");

	private final HttpStatus httpStatusCode;
	private final String code;

	ErrorCode(HttpStatus httpStatusCode, String code) {
		this.httpStatusCode = httpStatusCode;
		this.code = code;
	}

	public static class DetailMessage {

		private DetailMessage() {
		}

		// CLIENT
		public static final String URL_NOT_FOUND = "%s : 해당 경로는 존재하지 않는 경로입니다.";
		public static final String METHOD_NOT_ALLOWED = "%s : 해당 HTTP 메소드는 지원되지 않습니다. 허용 메소드 : %s";
		public static final String METHOD_ARGUMENT_TYPE_MISMATCH = "요청 파라미터에서 %s 값은 %s 타입이어야 합니다.";
		public static final String MISSING_REQUEST_PARAMETER = "요청 파라미터에서 %s 값은 필수입니다.";
		public static final String MEDIA_TYPE_NOT_SUPPORTED = "%s : 지원하지 않는 media type 입니다. 지원 type : %s";

		// SERVER
		public static final String SERVER_ERROR = "서버 내부에 문제가 생겼습니다.";
	}
}

0개의 댓글