Replies: 3 comments
-
저는 아래와 같은 포멧을 주로 사용합니다!
이렇게 사용하게 된다면 성공하게 된다면 클라이언트에서 response만 바라보면 되고, 실패하게 된다면 error만 바라보면 되기 때문에 간편했어요 :) 저의 ApiUtil은 아래와 같아요! public class APIUtils {
public static <T> ResponseEntity<ApiResult<T>> result(boolean success, T response, HttpStatus status) {
return new ResponseEntity<>(new ApiResult<>(success, response, null), status);
}
public static ResponseEntity<ApiResult<ApiError>> error(CustomException exception) {
return new ResponseEntity<>(
new ApiResult<>(false, null, new ApiError(exception))
, exception.getErrorCode().getStatus());
}
@Getter
@Setter
public static class ApiResult<T> {
private boolean success;
private T response;
private ApiError error;
public ApiResult(boolean success, T response, ApiError error) {
this.success = success;
this.response = response;
this.error = error;
}
public ApiResult() {
}
}
@Getter
@Setter
public static class ApiError {
private String code;
private String message;
public ApiError(String code, String message) {
this.code = code;
this.message = message;
}
public ApiError() {
}
public ApiError(ErrorCode code) {
this(code.getCode(), code.getMessage());
}
public ApiError(CustomException exception) {
this(exception.getErrorCode());
}
}
} |
Beta Was this translation helpful? Give feedback.
0 replies
-
Controller@GetMapping("/recruitments/{recruitmentId}")
public RecruitmentDetailsResponse readRecruitmentDetails(@PathVariable("recruitmentId") final Long recruitmentId) {
return recruitmentDetailsFindService.findRecruitmentDetails(recruitmentId);
}
@GetMapping("/recruitments/popular")
public PopularRecruitmentsResponse readPopularRecruitments(@ModelAttribute PopularRecruitmentCond request) {
return popularRecruitmentsFindService.findPopularRecruitments(request);
}
@PostMapping("/studies/{studyId}/recruitments")
public RecruitmentDetailsResponse write(@PathVariable("studyId") final Long studyId, @RequestBody final WriteRecruitmentRequest request, @Parameter(hidden = true) @AuthUser final User user) {
return recruitmentService.write(user, request, studyId);
} ResponseBodyAdvice
@Component
@RestControllerAdvice
public final class CommonResponseAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(final MethodParameter returnType, final Class<? extends HttpMessageConverter<?>> converterType) {
return converterType.isAssignableFrom(MappingJackson2HttpMessageConverter.class);
}
@SneakyThrows
@Override
public Object beforeBodyWrite(Object body, final MethodParameter returnType, final MediaType selectedContentType, final Class<? extends HttpMessageConverter<?>> selectedConverterType, final ServerHttpRequest request, final ServerHttpResponse response)
{
final DataFieldName annotation = returnType.getMethodAnnotation(DataFieldName.class);
body = (annotation != null) ? CommonResponse.success(annotation.value(), body) : CommonResponse.success(body);
return body;
} ExceptionHandler
@Component
@RestControllerAdvice
public final class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public ResponseEntity<CommonResponse> handleException(Exception e) {
return toResponseEntity(e, e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
} |
Beta Was this translation helpful? Give feedback.
0 replies
-
24-08-12 회의 내용입니다. API 응답 모델1. 컨트롤러 반환 타입
2. POST
3. CSR vs SSR 기준이 모호함
4. ProblemDetail (RFC 9457)
결론1. 컨트롤러에서는 ResponseEntity를 반환한다.2. 예외가 발생하면 ProblemDetail을 활용한다.3. 성공: 2xx + ApiResponse / 실패: 4xx + ProblemDetail(+errorCode)로 세부 명시ex) 예시
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
API를 구현하면서 공통된 응답을 위해 모델을 만들 필요가 생겼습니다. 따라서 하단의 클래스를 만들었습니다.
이 구조는 컨트롤러에서 body에
ApiResponse
를 담아서 응답하는 구조입니다. 예외 발생시 ApiResponse.error(ErrorCode)를 호출하게 됩니다.모든 API에 공통되는 모델이므로 팀 내에서 합의가 필요할 것 같습니다. 의견있으시면 자유롭게 공유해주세요.
Beta Was this translation helpful? Give feedback.
All reactions