Response
1️⃣ ApiResponse 구조
public class ApiResponse<T> {
private T data;
private String code;
private String message;
@Getter
@JsonIgnore
private HttpStatus status;
public static <T> ApiResponse<T> success(T data, ResponseStatus status) {
return new ApiResponse<>(data, status.getCode(), status.getMessage(), status.getStatus());
}
public static <T> ApiResponse<T> error(T data, ResponseStatus status) {
return new ApiResponse<>(data, status.getCode(), status.getMessage(), status.getStatus());
}
}
ApiResponse의 구조는 아래와 같습니다.
T data
: response 해 줄 데이터의 값String code
: 내부적인 커스텀 코드의 값String message
: 메시지 값HttpStatus status
: http response header 상태를 위한 내부적인 http status code 값 (client에게 미노출)
왜 debug 요소는 없나요?
debug 요소를 넣지 않은 이유는 아래에서 나올
ResponseStatus
의 존재로 인해 추척이 쉬워지기 때문입니다. 또한 로그를 통해서도 추적이 쉽기도 합니다.
HttpStatus는 어떻게 활용되나요?
HttpStatus
가 어떻게 활용되는지는 아래에 페이지에 서술되어 있습니다.
https://www.hannah-log.site/portfolio/3/#3%EF%B8%8F%E2%83%A3-exception-handler--response-advice-%EA%B5%AC%EC%A1%B0
2️⃣ ApiResponse - ResponseStatus
ApiResponse
를 만들어주는 static 함수들에는 매개변수로 ResponseStatus
가 존재합니다.
public interface ResponseStatus {
int getStatus();
String getCode();
String getMessage();
}
ResponseStatus
는 인터페이스이며, 구현체는 getCode
와 getMessage
, getStatus
함수를 구현해주어야 합니다.
ResponseStatus
코드를 인터페이스로 만든 이유는 다음과 같습니다.
ApiResponse
와ErrorHandler
의 매개변수로 추상화 시킬 수 있습니다.- AOP에서
ResponseStatus
로 추상화 시킨 것을 응용할 수 있습니다. - 추후 다른 상태를 추가하는 등에 있어 확장성이 높아지고, 정형화시킬 수 있습니다.
기본적인 구현체는 2가지가 있습니다.
- SuccessStatus
public enum SuccessStatus implements ResponseStatus {
OK(HttpStatus.OK, "20000", "OK"),
CREATED(HttpStatus.CREATED, "20001", "생성되었습니다."),
UPDATED(HttpStatus.CREATED, "20001", "수정되었습니다."),
DELETED(HttpStatus.NO_CONTENT, "20004", "삭제되었습니다.")
;
private final HttpStatus status;
private final String code;
private final String message;
}
- ErrorStatus
public enum ErrorStatus implements ResponseStatus {
REQUEST_VALIDATION(HttpStatus.BAD_REQUEST, "40000", "잘못된 요청 구문입니다. 다시 확인해주세요."),
TYPE_ERROR(HttpStatus.BAD_REQUEST, "40000", "타입이 일치하지 않습니다. 다시 시도해주세요."),
URL_ERROR(HttpStatus.METHOD_NOT_ALLOWED, "40005", "지원하지 않는 HTTP method 입니다. 다시 시도해주세요.")
;
private final HttpStatus status;
private final String code;
private final String message;
}
3️⃣ ApiResponse - 사용
success의 사용
@PostMapping("/save")
public ApiResponse<SaveResponse> save(@RequestBody SaveRequest request) {
SaveResponse result = saveService.save(request);
return ApiResponse.success(result, SuccessStatus.CREATED);
}
error의 사용
@ExceptionHandler(BusinessException.class)
public ApiResponse<Object> businessException(BusinessException e) {
ErrorStatus errorStatus = e.getErrorCode();
return ApiResponse.error(null, errorStatus);
}
사용 규칙
- 생성은
static function
만으로 생성을 합니다. - 필요한
ResponseStatus
코드는 추가 작성하여 넣어줍니다.