현재 프로젝트는 sql 관련 세팅 (repo, querydsl 세팅등) 정도로 해두었다.
이번 포스팅에는 모든 리스폰스를 처리하는 dto를 통해 일관된 구조로 응답을 내려보도록 하겠다.
먼저 내가 원하는 형식의 dto를 하나 생성한다
/dto/Response.class
@Getter
@NoArgsConstructor
@Builder
public class Response<T> {
private String message;
private HttpStatus code;
@JsonInclude(JsonInclude.Include.NON_NULL)
private T data;
@Builder
public Response(String message, HttpStatus code, T data) {
this.message = message;
this.code = code;
this.data = data;
}
}
첫번째 String 의 경우 응답 결과에 따른 메시지, 오류 메시지를 담는 공간
code는 HttpStatus code를 담는 공간
그리고 제일 중요한 data 변수가 응답으로 보내줄 핵심 데이터가 들어갈 공간이다.
이 경우 data 변수안에 리스트, 정수, 문자열, 튜플등 가지각색에 데이터가 들어갈 가능성이 있는 변수 공간이기에 제네릭 Type으로 지정해서 만들어줬다.
그럼 dto를 만들었으니 이 DTO를 반환시켜줄 클래스를 생성하러 가보자
/utils/Api.class
public class Api {
public static <T> Response<T> success(HttpStatus code, String message, T data) {
return new Response<>(message, code.value(), data);
}
public static <T> Response<T> success(Integer code, String message, T data) {
return new Response<>(message, code, data);
}
public static <T> Response<T> error(Integer code, String message) {
return new Response<>(message, code, null);
}
public static <T> Response<T> error(HttpStatus code, String message) {
return new Response<>(message, code.value(), null);
}
}
단순 반환 구조, code의 경우 편의성을 위해 오버로딩 메서드 하나정도 더 만들어뒀다.
이제 이렇게 만든 구조를 테스트 코드를 사용해 테스트해보자
테스트코드@Test
void 정상_반환_테스트_숫자() throws Exception {
String message = "성공";
Integer data = 1;
Integer code = 200;
Response<Integer> response = Api.success(code, message, data);
assertNotNull(response);
assertEquals(code, response.getCode());
assertEquals(message, response.getMessage());
assertEquals(data, response.getData());
}
@Test
void 정상_반환_테스트_문자열() throws Exception {
String message = "성공";
String data = "데이터";
Integer code = 200;
Response<String> response = Api.success(code, message, data);
assertNotNull(response);
assertEquals(code, response.getCode());
assertEquals(message, response.getMessage());
assertEquals(data, response.getData());
}
@Test
void 정상_반환_테스트_리스트() throws Exception {
String message = "성공";
List<Integer> data = List.of(1, 2, 3);
Integer code = 200;
Response<List<Integer>> response = Api.success(code, message, data);
assertNotNull(response);
assertEquals(code, response.getCode());
assertEquals(message, response.getMessage());
assertEquals(data, response.getData());
}
@Test
void 정상_반환_테스트_HTTP_코드() throws Exception {
String message = "성공";
Integer data = 1;
Response<Integer> response = Api.success(HttpStatus.OK, message, data);
assertNotNull(response);
assertEquals(HttpStatus.OK.value(), response.getCode());
assertEquals(message, response.getMessage());
assertEquals(data, response.getData());
}
@Test
void 에러_반환_테스트() throws Exception {
Integer code = 400;
String message = "잘못된 요청";
Response<Void> response = Api.error(code, message);
assertNotNull(response);
assertEquals(message, response.getMessage());
assertEquals(code, response.getCode());
assertNull(response.getData());
}
@Test
public void 에러_반환_테스트_HTTP_코드() {
String message = "서버 오류";
Response<Void> response = Api.error(HttpStatus.INTERNAL_SERVER_ERROR, message);
assertNotNull(response);
assertEquals(message, response.getMessage());
assertEquals(HttpStatus.INTERNAL_SERVER_ERROR.value(), response.getCode()); // 검증
assertNull(response.getData());
}
테스트 결과도 잘 나오는걸 확인 할 수 있다.
새롭게 만든 클래스를 테스트해봤으니 이제 실제 컨트롤러에 적용해서 확인을 해보도록 하겠다.
/controller/HelloworldController.class
@RestController
@RequestMapping("/hello")
public class HelloWorldController {
@GetMapping("")
public Response<String> hello() {
return Api.success(200, "성공 메시지", "Hello World");
}
}
아주아주 간단한 컨트롤러이다. 호출해보면?
예상대로 반환값이랑 json 형태로 잘 넘어오는걸 확인할 수 있다!
다음은 에러처리를 위한 포스팅을 하겠다