본문 바로가기

IT

Spring Boot로 REST API 구현을 위한 ResponseEntity<> 커스텀

728x90

ResponseEntity<>를 작성할 때 header, body, status code를 분리하여 REST API를 구현하였는데  잘못된 요청 시도에서 body에 잘못된 요청이라는 정보를 편리하게 싣고 상태 코드도 커스텀하여 body에 추가하려한다. 따라서 필자는 Result Data 줄여서 RsData라는 클래스를 만들어서 활용하였다.

@Getter
@Setter
@AllArgsConstructor
public class RsData<T> {
    private String resultCode;
    private String msg;
    private T data;

    public static <T> RsData<T> of(String resultCode, String msg, T data) {
        return new RsData<>(resultCode, msg, data);
    }

    public static <T> RsData<T> of(String resultCode, String msg) {
        return of(resultCode, msg, null);
    }

    public static <T> RsData<T> successOf(T data) {
        return of("S-1", "성공", data);
    }

    public static <T> RsData<T> failOf(T data) {
        return of("F-1", "실패", data);
    }

    public boolean isSuccess() {
        return resultCode.startsWith("S-1");
    }

    public boolean isFail() {
        return isSuccess() == false;
    }
}

RsData에는 resultCode와 전달한 msg, 그리고 데이터를 담을 data를 선언하였으며 성공과 실패 처리 함수를 추가하였다.

 

필자는 주로 공통된 기능을 담당하는 함수는 Util 클래스에서 만들어 사용한다. 

responseEntityOf 함수는 이전에 만든 RsData를 판단하여 상태코드를 판단할 수 있다. 

mapof 함수는 매개변수로 배열이 들어오면 그것을 LinkedHashMap의 key, value 조합으로 만들어지도록 구현했다. 

public class Util {
    public static <K, V> Map<K, V> mapOf(Object... args) {
        Map<K, V> map = new LinkedHashMap<>();

        int size = args.length / 2;

        for (int i = 0; i < size; i++) {
            int keyIndex = i * 2;
            int valueIndex = keyIndex + 1;

            K key = (K) args[keyIndex];
            V value = (V) args[valueIndex];

            map.put(key, value);
        }

        return map;
    }
    public static class spring {

        public static <T> ResponseEntity<RsData> responseEntityOf(RsData<T> rsData) {
            return responseEntityOf(rsData, null);
        }

        public static <T> ResponseEntity<RsData> responseEntityOf(RsData<T> rsData, HttpHeaders headers) {
            return new ResponseEntity<>(rsData, headers, rsData.isSuccess() ? HttpStatus.OK : HttpStatus.BAD_REQUEST);
        }

        public static HttpHeaders httpHeadersOf(String... args) {
            HttpHeaders headers = new HttpHeaders();

            Map<String, String> map = Util.mapOf(args);

            for (String key : map.keySet()) {
                String value = map.get(key);
                headers.set(key, value);
            }

            return headers;
        }
    }
}

 

이제 간단하게 API를 구현할 수 있다. 

실패 시 간단하게 msg와 커스텀한 상태 코드와 함께 보낼 수 있다.

//사용자 계정이 존재하지 않을 경우
return Util.spring.responseEntityOf(RsData.of("F-2", "일치하는 회원이 존재하지 않습니다."));

//비밀번호가 일치하지 않을 경우
return Util.spring.responseEntityOf(RsData.of("F-3", "비밀번호가 일치하지 않습니다."));

 

 

반대로 성공 시 "S-1"의 코드와 원하는 data를 보낼 수 있고 추가적으로 헤더에 값을 설정할 수 있다.

return Util.spring.responseEntityOf( RsData.of("S-1", "로그인 성공", data), header);