-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: apiPayload 세팅 #1
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BaseCode와 BaseErrorCode 인터페이스를 두개로 굳이 분리할 이유가 있을까 싶은게 에러 코드를 반환하는 상황이나 성공 코드를 반환하는 상황이나 갖고 있어야 할 정보로는 HttpStatus와 기본 응답 형태에 해당하는 isSuccess, code, message 필드로 동일할 것 같습니다.
추가로 현재 구현된 ApiResponse 클래스에서 사용하는 메소드로 클라이언트의 반환값을 설정해준다면 HttpStatus까지는 ApiResponse로 설정이 불가능한 것으로 보입니다. 아래 코드와 같이 사용한다고 생각하였을 때 응답 body에 해당하는 부분은 설정한 BAD_REQUEST에 해당하는 데이터로 반환이 되지만 실제 HttpStatus값은 200 OK로 설정되어 있는 것을 확인할 수 있습니다.
@PostMapping
public ApiResponse<String> postExample() {
return ApiResponse.onFailure(ErrorStatus._BAD_REQUEST.getCode(), ErrorStatus._BAD_REQUEST.getMessage(), null);
}

아마 Spring Framework의 ResponseEntity 키워드로 찾아보시면 반환되는 HttpStatus를 어떻게 커스텀할 수 있을지 파악하실 수 있을 것 같고 혹시 도움이 필요하시다면 카톡이나 코멘트로 남겨주세요!
그리고 예제 코드 짜면서 느낀건데 onFailure 함수도 BaseErrorCode 자체를 받아서 사용하는 편이 더 사용성이 좋아 보입니다..!
-> 이 부분 생각해보니 에러 상황일 경우 GeneralException을 던져서 Advice에서 받아 처리하는 로직으로 핸들링하는 것 같은데 Advice 클래스 확인해보니 onFailure를 사용하지 않는 것 같더라구요..?
@JsonProperty("isSuccess") | ||
private final Boolean isSuccess; | ||
private final String code; | ||
private final String message; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isSuccess 필드에만 @JsonProperty 어노테이션을 추가한 이유가 있나요?
private final String code; | ||
private final String message; | ||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
private T result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
페이지네이션 정보를 내려주는 경우도 있을텐데 이와 관련된 설정도 필요해 보입니다!
public static <T> ApiResponse<T> onSuccess(T result){ | ||
return new ApiResponse<>(true, SuccessStatus._OK.getCode() , SuccessStatus._OK.getMessage(), result); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분은 개인적인 사용성 측면의 피드백이긴 한데 클라이언트로 반환하는 값에 200 코드로 내려가는 경우더라도 result 필드가 없는 채로 반환되는 경우가 있을 것 같은데 이를 사용하는 입장에서 onSuccess(null) 보다는 onSuccess()를 호출하는 것이 더 사용하기 편해 보입니다!
public static <T> ApiResponse<T> of(BaseCode code, T result){ | ||
return new ApiResponse<>(true, code.getReasonHttpStatus().getCode() , code.getReasonHttpStatus().getMessage(), result); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분도 동일하게 result가 없는 상황에 대해서도 고려해보시면 좋을 것 같아요!
|
||
public interface BaseCode { | ||
|
||
ReasonDTO getReason(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reason이라는 네이밍을 봤을 때 어떤 필드인지 감이 잘 안 오는 것 같습니다
public ErrorReasonDTO getReasonHttpStatus() { | ||
return ErrorReasonDTO.builder() | ||
.message(message) | ||
.code(code) | ||
.isSuccess(false) | ||
.httpStatus(httpStatus) | ||
.build() | ||
; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HttpStatus를 확인하고자 하는 용도라면 HttpStatus만 반환해주면 되지 않을까요? 이 함수와 getReason() 함수가 필요한 상황 구분이 잘 되지 않는 것 같습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
하나하나 코드 따라 쳐보면서 정상 작동 확인했습니다 !! 수고 많으셨구 배워갑니다 ~~ LGTM 🫶🏻
ApiResponse 기본 구조
모든 응답 값에 포함되는
isSuccess
,code
,message
필드값과null
이 아닌 경우에만 반환될pageInfo
,result
필드를 정의하였습니다.PageInfo
의 경우 아래와 같은 구조로 되어있습니다.성공 코드에 대한 반환값 생성 함수
모든 필드값을 받아서
ApiResponse
객체를 생성하여ResponseEntity
의 형태가 감싼 응답 형태를 반환하도록 구성하였습니다. 해당 함수는 다른onSuccess
함수에서 사용됩니다.data 반환 메소드
data를 포함한 응답 값을 반환해주고자 할 경우, 반환하고자 하는
SuccessStatus
객체와result
객체를 받아와 �위에서 정의한 onSuccess 함수가 호출되도록 구성하였습니다.아래는 컨트롤러에서 해당 메소드를 사용하는 예시입니다.
기본 응답값 반환 메소드
isSuccess
,code
,message
만 반환할 경우 컨트롤러에서 SuccessStatus를 넘겨주면onSuccess(status, page, result)
함수를 재활용하여 해당 메소드에 result 값과 page 정보가 null 로 설정되도록 구성하였습니다.아래는 컨트롤러에서 해당 메소드를 사용하는 예시입니다.
예외에 대한 응답값 반환 메소드
예외가 발생한 경우
ExceptionAdvice
에서 스프링 컨테이너 내 발생하는 모든 예외상황을 받아와ApiResponse.onFailure()
메서드를 호출하도록 설정하였습니다.ApiResponse
에서는ErrorStatus
를 받아서ApiResponse
객체를 만들어주고, 이를ResponseEntity
로 감싼 응답 형태를 반환해주도록 구성하였습니다.현재 프로젝트 상에서는 모든 예외처리에 대한 응답값을 반환하는 주체가
ErrorExceptionHandler
에서 처리해주고 있기 때문에 실제 개발 시에는 원하는 예외 상황에서 다음과 같이 예외를 발생시켜주면 됩니다.페이지네이션 정보를 포함한 응답값 반환 메소드
페이지네이션을 적용할 경우
page
객체에PageInfo
세팅을 위해 필요한 정보들과 data가 함께 들어가 있기 때문에page
정보에 따라PageInfo
객체를 만들어주고 기본onSuccess
함수에 전달해줍니다.아래는 컨트롤러에서 해당 메소드를 사용하는 예시입니다.
현재 해당하는 코드는 데이터베이스가 설정되기 전이므로 주석처리 해두었습니다. (데이터소스를 찾을 수 없기 때문에 테스트 시 실행 안 됨)
data를 반환하는 컨트롤러와 에러를 던지는 컨트롤러에 대한 테스트코드를 작성해두었고, 두 테스트 모두 통과하였습니다.