개발을 하다보면 Controller의 반환 구조에 대해 정해진 구조가 필요함을 느낄 때가 간혹 있다. 그러한 상황에서 ResponseEntity 를 사용해도 되지만
직접 커스텀하여 코드를 작성해보기로 하였다.
먼저 응답 구조를 DTO로 하나 생성해준다.
@Getter
public class Response<T> {
private final Boolean result;
private final Integer status;
private final String message;
@JsonInclude(JsonInclude.Include.NON_NULL)
private final T data;
@Builder
public Response(Boolean result, Integer status, String message, T data) {
this.result = result;
this.status = status;
this.message = message;
this.data = data;
}
}
나같은 경우는 위와 같이 작성하였고, 다른 값이 필요하거나 message 같이 필요 없다고 생각되는 필드는 과감하게 제거해도 된다.
생성한 DTO를 적당한 클래스를 만들어 return 시켜주는 메서드를 만들어준다.
public class ApiUtils {
public static <T> Response<T> success(Integer status, String message, T data) {
return new Response<>(true, status, message, data);
}
public static <T> Response<T> success(HttpStatus status, String message, T data) {
return new Response<>(true, status.value(), message, data);
}
}
ApiUtils 안에 코드를 작성해두었다. status를 Integer로 받는 메서드는 커스텀 status, HttpStatus로 받는 메서드는 미리 정의된 상태코드만 받을 수 있는 메서드로 총 두가지 메서드를 오버로딩해두었다.
그리고 컨트롤러에서 메서드를 만들 때 반환타입과 리턴을 위에 작성한 코드에 맞추면 된다.
@GetMapping("/{review_id}")
@Operation(summary = "댓글 리스트 조회")
public Response<List<CommentListResponse>> getList(@PathVariable("review_id") Long reviewId) {
return ApiUtils.success(HttpStatus.OK, "댓글 리스트 조회 성공", commentService.getListByReview(reviewId));
}
이렇게 개발을 하면 스웨거에서도 Example Response에서도 DTO의 구조가 잘 나온다.
다음은 공통 응답 구조와 동일 공통 에러 응답을 작성하겠다.